Enable safe linters (#1786)

* Enable safe linters

Enable the linters dogsled, rowserrcheck, and sqlclosecheck.

These report no errors currently in the code base.

Enable misspell.

Misspell finds two spelling mistakes in comments, which are fixed by the
patch as well.

Add and sort linters which are relatively
safe to add over time. Comment them out for now.

* Close the response body

If we can get a HTTP response, it has a body which ought to be closed.

By doing so, we avoid potentially leaking connections.

* Enable the exportloopref linter

There are two places in the code with these warnings. Fix them while
enabling the linter.

* Remove redundant types in tests

If a slice already determines the type, the inner type declaration is
redundant. Remove the inner declarations.

* Mark autotag test cases as parallel

Autotag test cases is by far the outlier when it comes to test time.
While go test runs test cases in parallel,
it doesn't do so inside a given package, unless one marks the test cases
as parallel.

This change provides a significant speedup on a 8-core machine for test
runs.
This commit is contained in:
SmallCoccinelle
2021-10-03 02:48:03 +02:00
committed by GitHub
parent 17f5642ebd
commit a5ca8fc678
15 changed files with 81 additions and 27 deletions

View File

@@ -18,8 +18,24 @@ linters:
- unused - unused
- varcheck - varcheck
# Linters added by the stash project # Linters added by the stash project
# - bodyclose
- dogsled
# - errorlint
# - exhaustive
- exportloopref
# - goconst
# - gocritic
# - goerr113
- gofmt - gofmt
# - gosec
# - ifshort
- misspell
# - nakedret
# - noctx
# - paralleltest
- revive - revive
- rowserrcheck
- sqlclosecheck
linters-settings: linters-settings:
gofmt: gofmt:
@@ -63,5 +79,4 @@ linters-settings:
- name: unused-parameter - name: unused-parameter
disabled: true disabled: true
- name: unreachable-code - name: unreachable-code
- name: redefines-builtin-id - name: redefines-builtin-id

View File

@@ -12,6 +12,8 @@ import (
const galleryExt = "zip" const galleryExt = "zip"
func TestGalleryPerformers(t *testing.T) { func TestGalleryPerformers(t *testing.T) {
t.Parallel()
const galleryID = 1 const galleryID = 1
const performerName = "performer name" const performerName = "performer name"
const performerID = 2 const performerID = 2
@@ -55,6 +57,8 @@ func TestGalleryPerformers(t *testing.T) {
} }
func TestGalleryStudios(t *testing.T) { func TestGalleryStudios(t *testing.T) {
t.Parallel()
const galleryID = 1 const galleryID = 1
const studioName = "studio name" const studioName = "studio name"
const studioID = 2 const studioID = 2
@@ -124,6 +128,8 @@ func TestGalleryStudios(t *testing.T) {
} }
func TestGalleryTags(t *testing.T) { func TestGalleryTags(t *testing.T) {
t.Parallel()
const galleryID = 1 const galleryID = 1
const tagName = "tag name" const tagName = "tag name"
const tagID = 2 const tagID = 2

View File

@@ -12,6 +12,8 @@ import (
const imageExt = "jpg" const imageExt = "jpg"
func TestImagePerformers(t *testing.T) { func TestImagePerformers(t *testing.T) {
t.Parallel()
const imageID = 1 const imageID = 1
const performerName = "performer name" const performerName = "performer name"
const performerID = 2 const performerID = 2
@@ -55,6 +57,8 @@ func TestImagePerformers(t *testing.T) {
} }
func TestImageStudios(t *testing.T) { func TestImageStudios(t *testing.T) {
t.Parallel()
const imageID = 1 const imageID = 1
const studioName = "studio name" const studioName = "studio name"
const studioID = 2 const studioID = 2
@@ -124,6 +128,8 @@ func TestImageStudios(t *testing.T) {
} }
func TestImageTags(t *testing.T) { func TestImageTags(t *testing.T) {
t.Parallel()
const imageID = 1 const imageID = 1
const tagName = "tag name" const tagName = "tag name"
const tagID = 2 const tagID = 2

View File

@@ -9,6 +9,8 @@ import (
) )
func TestPerformerScenes(t *testing.T) { func TestPerformerScenes(t *testing.T) {
t.Parallel()
type test struct { type test struct {
performerName string performerName string
expectedRegex string expectedRegex string
@@ -85,6 +87,8 @@ func testPerformerScenes(t *testing.T, performerName, expectedRegex string) {
} }
func TestPerformerImages(t *testing.T) { func TestPerformerImages(t *testing.T) {
t.Parallel()
type test struct { type test struct {
performerName string performerName string
expectedRegex string expectedRegex string
@@ -157,6 +161,8 @@ func testPerformerImages(t *testing.T, performerName, expectedRegex string) {
} }
func TestPerformerGalleries(t *testing.T) { func TestPerformerGalleries(t *testing.T) {
t.Parallel()
type test struct { type test struct {
performerName string performerName string
expectedRegex string expectedRegex string

View File

@@ -145,6 +145,8 @@ func generateTestTable(testName, ext string) []pathTestTable {
} }
func TestScenePerformers(t *testing.T) { func TestScenePerformers(t *testing.T) {
t.Parallel()
const sceneID = 1 const sceneID = 1
const performerName = "performer name" const performerName = "performer name"
const performerID = 2 const performerID = 2
@@ -188,6 +190,8 @@ func TestScenePerformers(t *testing.T) {
} }
func TestSceneStudios(t *testing.T) { func TestSceneStudios(t *testing.T) {
t.Parallel()
const sceneID = 1 const sceneID = 1
const studioName = "studio name" const studioName = "studio name"
const studioID = 2 const studioID = 2
@@ -257,6 +261,8 @@ func TestSceneStudios(t *testing.T) {
} }
func TestSceneTags(t *testing.T) { func TestSceneTags(t *testing.T) {
t.Parallel()
const sceneID = 1 const sceneID = 1
const tagName = "tag name" const tagName = "tag name"
const tagID = 2 const tagID = 2

View File

@@ -55,6 +55,8 @@ var testStudioCases = []testStudioCase{
} }
func TestStudioScenes(t *testing.T) { func TestStudioScenes(t *testing.T) {
t.Parallel()
for _, p := range testStudioCases { for _, p := range testStudioCases {
testStudioScenes(t, p) testStudioScenes(t, p)
} }
@@ -145,6 +147,8 @@ func testStudioScenes(t *testing.T, tc testStudioCase) {
} }
func TestStudioImages(t *testing.T) { func TestStudioImages(t *testing.T) {
t.Parallel()
for _, p := range testStudioCases { for _, p := range testStudioCases {
testStudioImages(t, p) testStudioImages(t, p)
} }
@@ -234,6 +238,8 @@ func testStudioImages(t *testing.T, tc testStudioCase) {
} }
func TestStudioGalleries(t *testing.T) { func TestStudioGalleries(t *testing.T) {
t.Parallel()
for _, p := range testStudioCases { for _, p := range testStudioCases {
testStudioGalleries(t, p) testStudioGalleries(t, p)
} }

View File

@@ -55,6 +55,8 @@ var testTagCases = []testTagCase{
} }
func TestTagScenes(t *testing.T) { func TestTagScenes(t *testing.T) {
t.Parallel()
for _, p := range testTagCases { for _, p := range testTagCases {
testTagScenes(t, p) testTagScenes(t, p)
} }
@@ -141,6 +143,8 @@ func testTagScenes(t *testing.T, tc testTagCase) {
} }
func TestTagImages(t *testing.T) { func TestTagImages(t *testing.T) {
t.Parallel()
for _, p := range testTagCases { for _, p := range testTagCases {
testTagImages(t, p) testTagImages(t, p)
} }
@@ -226,6 +230,8 @@ func testTagImages(t *testing.T, tc testTagCase) {
} }
func TestTagGalleries(t *testing.T) { func TestTagGalleries(t *testing.T) {
t.Parallel()
for _, p := range testTagCases { for _, p := range testTagCases {
testTagGalleries(t, p) testTagGalleries(t, p)
} }

View File

@@ -112,6 +112,7 @@ func DetectLogLevel(line string) (*PluginLogLevel, string) {
var level *PluginLogLevel var level *PluginLogLevel
for _, l := range validLevels { for _, l := range validLevels {
if l.char == char { if l.char == char {
l := l // Make a copy of the loop variable
level = &l level = &l
break break
} }

View File

@@ -251,7 +251,7 @@ func (s *singleton) Generate(ctx context.Context, input models.GenerateMetadataI
// Start measuring how long the generate has taken. (consider moving this up) // Start measuring how long the generate has taken. (consider moving this up)
start := time.Now() start := time.Now()
if err = instance.Paths.Generated.EnsureTmpDir(); err != nil { if err = instance.Paths.Generated.EnsureTmpDir(); err != nil {
logger.Warnf("could not create temprary directory: %v", err) logger.Warnf("could not create temporary directory: %v", err)
} }
for _, scene := range scenes { for _, scene := range scenes {

View File

@@ -148,32 +148,32 @@ var scenarios []testScenario
func initTestTable() { func initTestTable() {
scenarios = []testScenario{ scenarios = []testScenario{
testScenario{ {
createFullMovie(movieID, studioID), createFullMovie(movieID, studioID),
createFullJSONMovie(studioName, frontImage, backImage), createFullJSONMovie(studioName, frontImage, backImage),
false, false,
}, },
testScenario{ {
createEmptyMovie(emptyID), createEmptyMovie(emptyID),
createEmptyJSONMovie(), createEmptyJSONMovie(),
false, false,
}, },
testScenario{ {
createFullMovie(errFrontImageID, studioID), createFullMovie(errFrontImageID, studioID),
nil, nil,
true, true,
}, },
testScenario{ {
createFullMovie(errBackImageID, studioID), createFullMovie(errBackImageID, studioID),
nil, nil,
true, true,
}, },
testScenario{ {
createFullMovie(errStudioMovieID, errStudioID), createFullMovie(errStudioMovieID, errStudioID),
nil, nil,
true, true,
}, },
testScenario{ {
createFullMovie(missingStudioMovieID, missingStudioID), createFullMovie(missingStudioMovieID, missingStudioID),
createFullJSONMovie("", frontImage, backImage), createFullJSONMovie("", frontImage, backImage),
false, false,

View File

@@ -168,17 +168,17 @@ var scenarios []testScenario
func initTestTable() { func initTestTable() {
scenarios = []testScenario{ scenarios = []testScenario{
testScenario{ {
*createFullPerformer(performerID, performerName), *createFullPerformer(performerID, performerName),
createFullJSONPerformer(performerName, image), createFullJSONPerformer(performerName, image),
false, false,
}, },
testScenario{ {
createEmptyPerformer(noImageID), createEmptyPerformer(noImageID),
createEmptyJSONPerformer(), createEmptyJSONPerformer(),
false, false,
}, },
testScenario{ {
*createFullPerformer(errImageID, performerName), *createFullPerformer(errImageID, performerName),
nil, nil,
true, true,

View File

@@ -17,6 +17,7 @@ func findArg(args []*models.PluginArgInput, name string) *models.PluginArgInput
func applyDefaultArgs(args []*models.PluginArgInput, defaultArgs map[string]string) []*models.PluginArgInput { func applyDefaultArgs(args []*models.PluginArgInput, defaultArgs map[string]string) []*models.PluginArgInput {
for k, v := range defaultArgs { for k, v := range defaultArgs {
if arg := findArg(args, k); arg == nil { if arg := findArg(args, k); arg == nil {
v := v // Copy v, because it's being exported out of the loop
args = append(args, &models.PluginArgInput{ args = append(args, &models.PluginArgInput{
Key: k, Key: k,
Value: &models.PluginValueInput{ Value: &models.PluginValueInput{

View File

@@ -223,6 +223,7 @@ func getRemoteCDPWSAddress(address string) (string, error) {
if err != nil { if err != nil {
return "", err return "", err
} }
defer resp.Body.Close()
var result map[string]interface{} var result map[string]interface{}
var json = jsoniter.ConfigCompatibleWithStandardLibrary var json = jsoniter.ConfigCompatibleWithStandardLibrary

View File

@@ -53,9 +53,9 @@ const htmlDoc1 = `
<b>Country of Origin:</b> <b>Country of Origin:</b>
</td> </td>
<td class="paramvalue"> <td class="paramvalue">
<span class="country-us"> <span class="country-us">
United States United States
<span> <span>
</span></span></td> </span></span></td>
@@ -661,7 +661,7 @@ func verifyPerformers(t *testing.T, expectedNames []string, expectedURLs []strin
t.Errorf("Expected performer name %s, got %s", expectedName, actualName) t.Errorf("Expected performer name %s, got %s", expectedName, actualName)
} }
if expectedURL != actualURL { if expectedURL != actualURL {
t.Errorf("Expected perfromer URL %s, got %s", expectedName, actualName) t.Errorf("Expected performer URL %s, got %s", expectedName, actualName)
} }
i++ i++
} }
@@ -741,7 +741,7 @@ func TestLoadXPathScraperFromYAML(t *testing.T) {
const yamlStr = `name: Test const yamlStr = `name: Test
performerByURL: performerByURL:
- action: scrapeXPath - action: scrapeXPath
url: url:
- test.com - test.com
scraper: performerScraper scraper: performerScraper
xPathScrapers: xPathScrapers:
@@ -755,11 +755,11 @@ xPathScrapers:
postProcess: postProcess:
- parseDate: January 2, 2006 - parseDate: January 2, 2006
Tags: Tags:
Name: //tags Name: //tags
Movies: Movies:
Name: //movies Name: //movies
Performers: Performers:
Name: //performers Name: //performers
Studio: Studio:
Name: //studio Name: //studio
` `
@@ -848,13 +848,13 @@ func TestSubScrape(t *testing.T) {
yamlStr := `name: Test yamlStr := `name: Test
performerByURL: performerByURL:
- action: scrapeXPath - action: scrapeXPath
url: url:
- ` + ts.URL + ` - ` + ts.URL + `
scraper: performerScraper scraper: performerScraper
xPathScrapers: xPathScrapers:
performerScraper: performerScraper:
performer: performer:
Name: Name:
selector: //div/a/@href selector: //div/a/@href
postProcess: postProcess:
- replace: - replace:

View File

@@ -119,32 +119,32 @@ var scenarios []testScenario
func initTestTable() { func initTestTable() {
scenarios = []testScenario{ scenarios = []testScenario{
testScenario{ {
createFullStudio(studioID, parentStudioID), createFullStudio(studioID, parentStudioID),
createFullJSONStudio(parentStudioName, image, []string{"alias"}), createFullJSONStudio(parentStudioName, image, []string{"alias"}),
false, false,
}, },
testScenario{ {
createEmptyStudio(noImageID), createEmptyStudio(noImageID),
createEmptyJSONStudio(), createEmptyJSONStudio(),
false, false,
}, },
testScenario{ {
createFullStudio(errImageID, parentStudioID), createFullStudio(errImageID, parentStudioID),
nil, nil,
true, true,
}, },
testScenario{ {
createFullStudio(missingParentStudioID, missingStudioID), createFullStudio(missingParentStudioID, missingStudioID),
createFullJSONStudio("", image, nil), createFullJSONStudio("", image, nil),
false, false,
}, },
testScenario{ {
createFullStudio(errStudioID, errParentStudioID), createFullStudio(errStudioID, errParentStudioID),
nil, nil,
true, true,
}, },
testScenario{ {
createFullStudio(errAliasID, parentStudioID), createFullStudio(errAliasID, parentStudioID),
nil, nil,
true, true,