From 251b205f54389853ac84eb9b1369bbfb3f9211ed Mon Sep 17 00:00:00 2001
From: Sergey Vilgelm <sergey.vilgelm@ibm.com>
Date: Sat, 20 Feb 2021 18:55:11 -0600
Subject: [PATCH] Deprecate `Interfacer` linter (#1755)

---
 .golangci.yml                 |  2 +-
 pkg/commands/run.go           |  5 +++++
 pkg/config/config.go          |  3 ++-
 pkg/lint/linter/config.go     | 18 ++++++++++++++----
 pkg/lint/lintersdb/manager.go |  3 ++-
 pkg/lint/runner.go            | 12 ++++++++++--
 test/testdata/interfacer.go   |  2 +-
 test/testshared/testshared.go |  4 +++-
 8 files changed, 38 insertions(+), 11 deletions(-)

diff --git a/.golangci.yml b/.golangci.yml
index d8806b14..08460ba9 100644
--- a/.golangci.yml
+++ b/.golangci.yml
@@ -88,7 +88,6 @@ linters:
     - gosimple
     - govet
     - ineffassign
-    - interfacer
     - lll
     - misspell
     - nakedret
@@ -113,6 +112,7 @@ linters:
   # - godot
   # - godox
   # - goerr113
+  # - interfacer
   # - maligned
   # - nestif
   # - prealloc
diff --git a/pkg/commands/run.go b/pkg/commands/run.go
index 357e2746..c255e246 100644
--- a/pkg/commands/run.go
+++ b/pkg/commands/run.go
@@ -82,6 +82,11 @@ func initFlagSet(fs *pflag.FlagSet, cfg *config.Config, m *lintersdb.Manager, is
 	fs.StringVar(&oc.PathPrefix, "path-prefix", "", wh("Path prefix to add to output"))
 	hideFlag("print-welcome") // no longer used
 
+	fs.BoolVar(&cfg.InternalCmdTest, "internal-cmd-test", false, wh("Option is used only for testing golangci-lint command, don't use it"))
+	if err := fs.MarkHidden("internal-cmd-test"); err != nil {
+		panic(err)
+	}
+
 	// Run config
 	rc := &cfg.Run
 	fs.StringVar(&rc.ModulesDownloadMode, "modules-download-mode", "",
diff --git a/pkg/config/config.go b/pkg/config/config.go
index 0aae4914..fdf57875 100644
--- a/pkg/config/config.go
+++ b/pkg/config/config.go
@@ -663,7 +663,8 @@ type Config struct {
 	Severity        Severity
 	Version         Version
 
-	InternalTest bool // Option is used only for testing golangci-lint code, don't use it
+	InternalCmdTest bool `mapstructure:"internal-cmd-test"` // Option is used only for testing golangci-lint command, don't use it
+	InternalTest    bool // Option is used only for testing golangci-lint code, don't use it
 }
 
 func NewDefault() *Config {
diff --git a/pkg/lint/linter/config.go b/pkg/lint/linter/config.go
index 4ec83525..86f78e5a 100644
--- a/pkg/lint/linter/config.go
+++ b/pkg/lint/linter/config.go
@@ -22,10 +22,11 @@ type Config struct {
 	InPresets        []string
 	AlternativeNames []string
 
-	OriginalURL     string // URL of original (not forked) repo, needed for autogenerated README
-	CanAutoFix      bool
-	IsSlow          bool
-	DoesChangeTypes bool
+	OriginalURL       string // URL of original (not forked) repo, needed for autogenerated README
+	CanAutoFix        bool
+	IsSlow            bool
+	DoesChangeTypes   bool
+	DeprecatedMessage string
 }
 
 func (lc *Config) ConsiderSlow() *Config {
@@ -73,6 +74,15 @@ func (lc *Config) WithChangeTypes() *Config {
 	return lc
 }
 
+func (lc *Config) Deprecated(message string) *Config {
+	lc.DeprecatedMessage = message
+	return lc
+}
+
+func (lc *Config) IsDeprecated() bool {
+	return lc.DeprecatedMessage != ""
+}
+
 func (lc *Config) AllNames() []string {
 	return append([]string{lc.Name()}, lc.AlternativeNames...)
 }
diff --git a/pkg/lint/lintersdb/manager.go b/pkg/lint/lintersdb/manager.go
index bdf7a870..035ab151 100644
--- a/pkg/lint/lintersdb/manager.go
+++ b/pkg/lint/lintersdb/manager.go
@@ -177,7 +177,8 @@ func (m Manager) GetAllSupportedLinterConfigs() []*linter.Config {
 		linter.NewConfig(golinters.NewInterfacer()).
 			WithLoadForGoAnalysis().
 			WithPresets(linter.PresetStyle).
-			WithURL("https://github.com/mvdan/interfacer"),
+			WithURL("https://github.com/mvdan/interfacer").
+			Deprecated("The repository of the linter has been archived by the owner."),
 		linter.NewConfig(golinters.NewUnconvert()).
 			WithLoadForGoAnalysis().
 			WithPresets(linter.PresetStyle).
diff --git a/pkg/lint/runner.go b/pkg/lint/runner.go
index 63e6ad71..57884747 100644
--- a/pkg/lint/runner.go
+++ b/pkg/lint/runner.go
@@ -8,6 +8,7 @@ import (
 	"strings"
 
 	"github.com/pkg/errors"
+	gopackages "golang.org/x/tools/go/packages"
 
 	"github.com/golangci/golangci-lint/internal/errorutil"
 	"github.com/golangci/golangci-lint/pkg/config"
@@ -20,8 +21,6 @@ import (
 	"github.com/golangci/golangci-lint/pkg/result"
 	"github.com/golangci/golangci-lint/pkg/result/processors"
 	"github.com/golangci/golangci-lint/pkg/timeutils"
-
-	gopackages "golang.org/x/tools/go/packages"
 )
 
 type Runner struct {
@@ -50,6 +49,15 @@ func NewRunner(cfg *config.Config, log logutils.Log, goenv *goutil.Env, es *lint
 		return nil, errors.Wrap(err, "failed to get enabled linters")
 	}
 
+	// print deprecated messages
+	if !cfg.InternalCmdTest {
+		for name, lc := range enabledLinters {
+			if lc.IsDeprecated() {
+				log.Warnf("The linter '%s' is deprecated due to: %s", name, lc.DeprecatedMessage)
+			}
+		}
+	}
+
 	return &Runner{
 		Processors: []processors.Processor{
 			processors.NewCgo(goenv),
diff --git a/test/testdata/interfacer.go b/test/testdata/interfacer.go
index 55b1e291..ef8010aa 100644
--- a/test/testdata/interfacer.go
+++ b/test/testdata/interfacer.go
@@ -1,4 +1,4 @@
-//args: -Einterfacer
+//args: -Einterfacer --internal-cmd-test
 package testdata
 
 import "io"
diff --git a/test/testshared/testshared.go b/test/testshared/testshared.go
index 8effe2ba..c1a89d69 100644
--- a/test/testshared/testshared.go
+++ b/test/testshared/testshared.go
@@ -94,7 +94,9 @@ func (r *LintRunner) Run(args ...string) *RunResult {
 func (r *LintRunner) RunCommand(command string, args ...string) *RunResult {
 	r.Install()
 
-	runArgs := append([]string{command}, args...)
+	runArgs := append([]string{command}, "--internal-cmd-test")
+	runArgs = append(runArgs, args...)
+
 	defer func(startedAt time.Time) {
 		r.log.Infof("ran [../golangci-lint %s] in %s", strings.Join(runArgs, " "), time.Since(startedAt))
 	}(time.Now())