Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v5
with:
go-version: 1.25.x
go-version: 1.27.x

- name: Install Node
uses: actions/setup-node@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:

- uses: actions/setup-go@v5
with:
go-version: 1.25.x
go-version: 1.27.x

- uses: actions/setup-node@v4
with:
Expand Down
8 changes: 7 additions & 1 deletion .github/workflows/golangci-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,16 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: 1.25.x
go-version: 1.27.x
- run: mkdir frontend/build && touch frontend/build/dummy
- name: Run golangci-lint
uses: golangci/golangci-lint-action@v8
with:
# Optional: version of golangci-lint to use in form of v1.2 or v1.2.3 or `latest` to use the latest version
version: latest
- name: Check modernizations
run: |
if ! go fix -diff -tags=integration ./...; then
echo "::error::Modernizations available. Run 'make fix' locally and commit the changes."
exit 1
fi
2 changes: 1 addition & 1 deletion .golangci.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
version: "2"
run:
go: "1.25"
go: "1.27"
linters:
enable:
- copyloopvar
Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ LDFLAGS := $(LDFLAGS)
test \
it \
fmt \
fix \
lint \
ui \
ui-start \
Expand Down Expand Up @@ -104,6 +105,10 @@ it:
fmt:
go fmt ./...

# Applies the modernizations suggested by the toolchain's fixers. Checked in CI.
fix:
go fix -tags=integration ./...

# Runs all configured linuters. golangci-lint needs to be installed locally first.
lint:
golangci-lint run
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/stashapp/stash-box

go 1.25.0
go 1.27.0

require (
github.com/99designs/gqlgen v0.17.90
Expand Down
4 changes: 2 additions & 2 deletions internal/api/directives.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ import (
"github.com/stashapp/stash-box/internal/models"
)

func IsUserOwnerDirective(ctx context.Context, obj interface{}, next graphql.Resolver) (interface{}, error) {
func IsUserOwnerDirective(ctx context.Context, obj any, next graphql.Resolver) (any, error) {
if err := auth.ValidateUserOrAdmin(ctx, obj.(*models.User).ID); err != nil {
return nil, err
}

return next(ctx)
}

func HasRoleDirective(ctx context.Context, obj interface{}, next graphql.Resolver, role models.RoleEnum) (interface{}, error) {
func HasRoleDirective(ctx context.Context, obj any, next graphql.Resolver, role models.RoleEnum) (any, error) {
if err := auth.ValidateRole(ctx, role); err != nil {
return nil, err
}
Expand Down
12 changes: 6 additions & 6 deletions internal/api/draft_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -223,28 +223,28 @@ func (s *draftTestRunner) testSceneDraftTagResolution() {
assert.NoError(s.t, err, "Error finding draft")
assert.NotNil(s.t, foundDraft.Data, "Draft data should not be nil")

draftData := foundDraft.Data.(map[string]interface{})
tags, ok := draftData["tags"].([]interface{})
draftData := foundDraft.Data.(map[string]any)
tags, ok := draftData["tags"].([]any)
assert.True(s.t, ok, "Tags should be an array")
assert.Equal(s.t, 4, len(tags), "Should have exactly 4 tags")

// Verify each tag
tag1Found := tags[0].(map[string]interface{})
tag1Found := tags[0].(map[string]any)
assert.Equal(s.t, "Tag", tag1Found["__typename"], "Tag 1 should be resolved")
assert.Equal(s.t, tag1ID.String(), tag1Found["id"], "Tag 1 ID should match")
assert.Equal(s.t, tag1Name, tag1Found["name"], "Tag 1 name should match")

tag2Found := tags[1].(map[string]interface{})
tag2Found := tags[1].(map[string]any)
assert.Equal(s.t, "Tag", tag2Found["__typename"], "Tag 2 should be resolved")
assert.Equal(s.t, tag2ID.String(), tag2Found["id"], "Tag 2 ID should match")
assert.Equal(s.t, tag2Name, tag2Found["name"], "Tag 2 name should match")

tag3Found := tags[2].(map[string]interface{})
tag3Found := tags[2].(map[string]any)
assert.Equal(s.t, "Tag", tag3Found["__typename"], "Tag 3 should be resolved")
assert.Equal(s.t, tag3ID.String(), tag3Found["id"], "Tag 3 ID should match")
assert.Equal(s.t, tag3Name, tag3Found["name"], "Tag 3 name should match")

unmatchedFound := tags[3].(map[string]interface{})
unmatchedFound := tags[3].(map[string]any)
assert.Equal(s.t, "DraftEntity", unmatchedFound["__typename"], "Unmatched tag should be DraftEntity")
assert.Equal(s.t, unmatchedTagName, unmatchedFound["name"], "Unmatched tag name should match")
}
Expand Down
10 changes: 3 additions & 7 deletions internal/api/edit_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package api_test

import (
"context"
"slices"
"testing"
"time"

Expand Down Expand Up @@ -107,12 +108,7 @@ func (s *editTestRunner) testVotePermissionsPromotion() {
func (s *editTestRunner) verifyUserRolePromotion(user *models.User) {
assert.Eventually(s.t, func() bool {
roles, _ := s.resolver.User().Roles(s.ctx, user)
for _, role := range roles {
if role == models.RoleEnumVote {
return true
}
}
return false
return slices.Contains(roles, models.RoleEnumVote)
}, 5*time.Second, 25*time.Millisecond, "user was not promoted to Vote role")
}

Expand Down Expand Up @@ -289,7 +285,7 @@ func (s *editTestRunner) testDeletedVotersRetainVotes() {
// survive with user_id set to NULL, which also exercises multiple NULL
// user_ids coexisting on a single edit.
var voterIDs []uuid.UUID
for i := 0; i < 2; i++ {
for range 2 {
voter, err := s.createTestUser(nil, []models.RoleEnum{models.RoleEnumVote})
assert.NoError(s.t, err)
voterIDs = append(voterIDs, voter.ID)
Expand Down
50 changes: 25 additions & 25 deletions internal/api/graphql_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,10 @@ type performerDraftOutput struct {
}

type draftOutput struct {
ID string `json:"id"`
Created string `json:"created"`
Expires string `json:"expires"`
Data interface{} `json:"data"`
ID string `json:"id"`
Created string `json:"created"`
Expires string `json:"expires"`
Data any `json:"data"`
}

func (d draftOutput) UUID() uuid.UUID {
Expand Down Expand Up @@ -289,7 +289,7 @@ func makeFragment(t reflect.Type) string {
if ft.Kind() == reflect.Slice {
ft = ft.Elem()
}
if ft.Kind() == reflect.Ptr {
if ft.Kind() == reflect.Pointer {
ft = ft.Elem()
}

Expand All @@ -311,7 +311,7 @@ func (c *graphqlClient) createScene(input models.SceneCreateInput) (*sceneOutput
q := `
mutation SceneCreate($input: SceneCreateInput!) {
sceneCreate(input: $input) {
` + makeFragment(reflect.TypeOf(sceneOutput{})) + `
` + makeFragment(reflect.TypeFor[sceneOutput]()) + `
}
}`

Expand All @@ -329,7 +329,7 @@ func (c *graphqlClient) findScene(id uuid.UUID) (*sceneOutput, error) {
q := `
query FindScene($id: ID!) {
findScene(id: $id) {
` + makeFragment(reflect.TypeOf(sceneOutput{})) + `
` + makeFragment(reflect.TypeFor[sceneOutput]()) + `
}
}`

Expand All @@ -347,7 +347,7 @@ func (c *graphqlClient) findScenesBySceneFingerprints(sceneFingerprints [][]mode
q := `
query FindScenesBySceneFingerprints($input: [[FingerprintQueryInput!]!]!) {
findScenesBySceneFingerprints(fingerprints: $input) {
` + makeFragment(reflect.TypeOf(sceneOutput{})) + `
` + makeFragment(reflect.TypeFor[sceneOutput]()) + `
}
}`

Expand All @@ -365,7 +365,7 @@ func (c *graphqlClient) queryScenes(input models.SceneQueryInput) (*queryScenesR
q := `
query QueryScenes($input: SceneQueryInput!) {
queryScenes(input: $input) {
` + makeFragment(reflect.TypeOf(queryScenesResultType{})) + `
` + makeFragment(reflect.TypeFor[queryScenesResultType]()) + `
}
}`

Expand All @@ -383,7 +383,7 @@ func (c *graphqlClient) updateScene(updateInput models.SceneUpdateInput) (*scene
q := `
mutation SceneUpdate($input: SceneUpdateInput!) {
sceneUpdate(input: $input) {
` + makeFragment(reflect.TypeOf(sceneOutput{})) + `
` + makeFragment(reflect.TypeFor[sceneOutput]()) + `
}
}`

Expand Down Expand Up @@ -502,7 +502,7 @@ func (c *graphqlClient) createPerformer(input models.PerformerCreateInput) (*per
q := `
mutation PerformerCreate($input: PerformerCreateInput!) {
performerCreate(input: $input) {
` + makeFragment(reflect.TypeOf(performerOutput{})) + `
` + makeFragment(reflect.TypeFor[performerOutput]()) + `
}
}`

Expand All @@ -520,7 +520,7 @@ func (c *graphqlClient) findPerformer(id uuid.UUID) (*performerOutput, error) {
q := `
query FindPerformer($id: ID!) {
findPerformer(id: $id) {
` + makeFragment(reflect.TypeOf(performerOutput{})) + `
` + makeFragment(reflect.TypeFor[performerOutput]()) + `
}
}`

Expand All @@ -538,7 +538,7 @@ func (c *graphqlClient) createStudio(input models.StudioCreateInput) (*studioOut
q := `
mutation StudioCreate($input: StudioCreateInput!) {
studioCreate(input: $input) {
` + makeFragment(reflect.TypeOf(studioOutput{})) + `
` + makeFragment(reflect.TypeFor[studioOutput]()) + `
}
}`

Expand All @@ -556,7 +556,7 @@ func (c *graphqlClient) findStudio(id uuid.UUID) (*studioOutput, error) {
q := `
query FindStudio($id: ID!) {
findStudio(id: $id) {
` + makeFragment(reflect.TypeOf(studioOutput{})) + `
` + makeFragment(reflect.TypeFor[studioOutput]()) + `
}
}`

Expand All @@ -574,7 +574,7 @@ func (c *graphqlClient) createTag(input models.TagCreateInput) (*tagOutput, erro
q := `
mutation TagCreate($input: TagCreateInput!) {
tagCreate(input: $input) {
` + makeFragment(reflect.TypeOf(tagOutput{})) + `
` + makeFragment(reflect.TypeFor[tagOutput]()) + `
}
}`

Expand All @@ -592,7 +592,7 @@ func (c *graphqlClient) findSite(id uuid.UUID) (*siteOutput, error) {
q := `
query FindSite($id: ID!) {
findSite(id: $id) {
` + makeFragment(reflect.TypeOf(siteOutput{})) + `
` + makeFragment(reflect.TypeFor[siteOutput]()) + `
}
}`

Expand All @@ -610,7 +610,7 @@ func (c *graphqlClient) querySites() (*querySitesResultType, error) {
q := `
query QuerySites {
querySites {
` + makeFragment(reflect.TypeOf(querySitesResultType{})) + `
` + makeFragment(reflect.TypeFor[querySitesResultType]()) + `
}
}`

Expand All @@ -628,7 +628,7 @@ func (c *graphqlClient) updateSite(input models.SiteUpdateInput) (*siteOutput, e
q := `
mutation SiteUpdate($input: SiteUpdateInput!) {
siteUpdate(input: $input) {
` + makeFragment(reflect.TypeOf(siteOutput{})) + `
` + makeFragment(reflect.TypeFor[siteOutput]()) + `
}
}`

Expand Down Expand Up @@ -662,7 +662,7 @@ func (c *graphqlClient) queryPerformers(input models.PerformerQueryInput) (*quer
q := `
query QueryPerformers($input: PerformerQueryInput!) {
queryPerformers(input: $input) {
` + makeFragment(reflect.TypeOf(queryPerformersResultType{})) + `
` + makeFragment(reflect.TypeFor[queryPerformersResultType]()) + `
}
}`

Expand All @@ -680,7 +680,7 @@ func (c *graphqlClient) queryStudios(input models.StudioQueryInput) (*queryStudi
q := `
query QueryStudios($input: StudioQueryInput!) {
queryStudios(input: $input) {
` + makeFragment(reflect.TypeOf(queryStudiosResultType{})) + `
` + makeFragment(reflect.TypeFor[queryStudiosResultType]()) + `
}
}`

Expand All @@ -698,7 +698,7 @@ func (c *graphqlClient) queryTags(input models.TagQueryInput) (*queryTagsResultT
q := `
query QueryTags($input: TagQueryInput!) {
queryTags(input: $input) {
` + makeFragment(reflect.TypeOf(queryTagsResultType{})) + `
` + makeFragment(reflect.TypeFor[queryTagsResultType]()) + `
}
}`

Expand All @@ -716,7 +716,7 @@ func (c *graphqlClient) queryTagCategories() (*queryTagCategoriesResultType, err
q := `
query QueryTagCategories {
queryTagCategories {
` + makeFragment(reflect.TypeOf(queryTagCategoriesResultType{})) + `
` + makeFragment(reflect.TypeFor[queryTagCategoriesResultType]()) + `
}
}`

Expand All @@ -734,7 +734,7 @@ func (c *graphqlClient) querySiteCategories() (*querySiteCategoriesResultType, e
q := `
query QuerySiteCategories {
querySiteCategories {
` + makeFragment(reflect.TypeOf(querySiteCategoriesResultType{})) + `
` + makeFragment(reflect.TypeFor[querySiteCategoriesResultType]()) + `
}
}`

Expand All @@ -752,7 +752,7 @@ func (c *graphqlClient) findTagOrAlias(name string) (*tagOutput, error) {
q := `
query FindTagOrAlias($name: String!) {
findTagOrAlias(name: $name) {
` + makeFragment(reflect.TypeOf(tagOutput{})) + `
` + makeFragment(reflect.TypeFor[tagOutput]()) + `
}
}`

Expand All @@ -770,7 +770,7 @@ func (c *graphqlClient) me() (*userOutput, error) {
q := `
query Me {
me {
` + makeFragment(reflect.TypeOf(userOutput{})) + `
` + makeFragment(reflect.TypeFor[userOutput]()) + `
}
}`

Expand Down
8 changes: 4 additions & 4 deletions internal/api/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -255,13 +255,13 @@ func (t *testRunner) doTest(test func()) {
test()
}

func (t *testRunner) fieldMismatch(expected interface{}, actual interface{}, field string) {
func (t *testRunner) fieldMismatch(expected any, actual any, field string) {
t.t.Helper()
t.t.Errorf("%s mismatch: %+v != %+v", field, actual, expected)
}

func (t *testRunner) updateContext(fields []string) context.Context {
variables := make(map[string]interface{})
variables := make(map[string]any)
for _, v := range fields {
variables[v] = true
}
Expand Down Expand Up @@ -635,11 +635,11 @@ func (s *testRunner) getEditStudioTarget(input *models.Edit) *models.Studio {
return tagTarget
}

func oneNil(l interface{}, r interface{}) bool {
func oneNil(l any, r any) bool {
return l != r && (l == nil || r == nil)
}

func bothNil(l interface{}, r interface{}) bool {
func bothNil(l any, r any) bool {
return l == nil && r == nil
}

Expand Down
Loading
Loading