🌐 AI搜索 & 代理 主页
fix issues related to source package imports (#507)

Fixes: #505
Fixes: #515
diff --git a/mockgen/internal/tests/extra_import/import.go b/mockgen/internal/tests/extra_import/import.go
new file mode 100644
index 0000000..50240da
--- /dev/null
+++ b/mockgen/internal/tests/extra_import/import.go
@@ -0,0 +1,12 @@
+// Package extra_import makes sure output does not import it. See #515.
+package extra_import
+
+//go:generate mockgen -destination mock.go -package extra_import . Foo
+
+type Message struct {
+	Text string
+}
+
+type Foo interface {
+	Bar(channels []string, message chan<- Message)
+}
diff --git a/mockgen/internal/tests/extra_import/mock.go b/mockgen/internal/tests/extra_import/mock.go
new file mode 100644
index 0000000..d8b0928
--- /dev/null
+++ b/mockgen/internal/tests/extra_import/mock.go
@@ -0,0 +1,46 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: github.com/golang/mock/mockgen/internal/tests/extra_import (interfaces: Foo)
+
+// Package extra_import is a generated GoMock package.
+package extra_import
+
+import (
+	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
+)
+
+// MockFoo is a mock of Foo interface.
+type MockFoo struct {
+	ctrl     *gomock.Controller
+	recorder *MockFooMockRecorder
+}
+
+// MockFooMockRecorder is the mock recorder for MockFoo.
+type MockFooMockRecorder struct {
+	mock *MockFoo
+}
+
+// NewMockFoo creates a new mock instance.
+func NewMockFoo(ctrl *gomock.Controller) *MockFoo {
+	mock := &MockFoo{ctrl: ctrl}
+	mock.recorder = &MockFooMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockFoo) EXPECT() *MockFooMockRecorder {
+	return m.recorder
+}
+
+// Bar mocks base method.
+func (m *MockFoo) Bar(arg0 []string, arg1 chan<- Message) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "Bar", arg0, arg1)
+}
+
+// Bar indicates an expected call of Bar.
+func (mr *MockFooMockRecorder) Bar(arg0, arg1 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Bar", reflect.TypeOf((*MockFoo)(nil).Bar), arg0, arg1)
+}
diff --git a/mockgen/internal/tests/missing_import/output/source_mock.go b/mockgen/internal/tests/missing_import/output/source_mock.go
new file mode 100644
index 0000000..082d10b
--- /dev/null
+++ b/mockgen/internal/tests/missing_import/output/source_mock.go
@@ -0,0 +1,47 @@
+// Code generated by MockGen. DO NOT EDIT.
+// Source: source.go
+
+// Package source is a generated GoMock package.
+package source
+
+import (
+	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
+	source "github.com/golang/mock/mockgen/internal/tests/missing_import/source"
+)
+
+// MockBar is a mock of Bar interface.
+type MockBar struct {
+	ctrl     *gomock.Controller
+	recorder *MockBarMockRecorder
+}
+
+// MockBarMockRecorder is the mock recorder for MockBar.
+type MockBarMockRecorder struct {
+	mock *MockBar
+}
+
+// NewMockBar creates a new mock instance.
+func NewMockBar(ctrl *gomock.Controller) *MockBar {
+	mock := &MockBar{ctrl: ctrl}
+	mock.recorder = &MockBarMockRecorder{mock}
+	return mock
+}
+
+// EXPECT returns an object that allows the caller to indicate expected use.
+func (m *MockBar) EXPECT() *MockBarMockRecorder {
+	return m.recorder
+}
+
+// Baz mocks base method.
+func (m *MockBar) Baz(arg0 source.Foo) {
+	m.ctrl.T.Helper()
+	m.ctrl.Call(m, "Baz", arg0)
+}
+
+// Baz indicates an expected call of Baz.
+func (mr *MockBarMockRecorder) Baz(arg0 interface{}) *gomock.Call {
+	mr.mock.ctrl.T.Helper()
+	return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Baz", reflect.TypeOf((*MockBar)(nil).Baz), arg0)
+}
diff --git a/mockgen/internal/tests/missing_import/source/source.go b/mockgen/internal/tests/missing_import/source/source.go
new file mode 100644
index 0000000..015576d
--- /dev/null
+++ b/mockgen/internal/tests/missing_import/source/source.go
@@ -0,0 +1,10 @@
+//go:generate mockgen -package source -destination=../output/source_mock.go -source=source.go
+
+// Package source makes sure output imports its. See #505.
+package source
+
+type Foo struct{}
+
+type Bar interface {
+	Baz(Foo)
+}
diff --git a/mockgen/mockgen.go b/mockgen/mockgen.go
index e02b752..f816b09 100644
--- a/mockgen/mockgen.go
+++ b/mockgen/mockgen.go
@@ -23,7 +23,6 @@
 	"encoding/json"
 	"flag"
 	"fmt"
-	"go/build"
 	"go/token"
 	"io"
 	"io/ioutil"
@@ -133,15 +132,14 @@
 	// "package.X" since "package" is this package). This can happen if the mock
 	// is output into an already existing package.
 	outputPackagePath := *selfPackage
-	if len(outputPackagePath) == 0 && len(*destination) > 0 {
-		dst, _ := filepath.Abs(filepath.Dir(*destination))
-		for _, prefix := range build.Default.SrcDirs() {
-			if strings.HasPrefix(dst, prefix) {
-				if rel, err := filepath.Rel(prefix, dst); err == nil {
-					outputPackagePath = rel
-					break
-				}
-			}
+	if outputPackagePath == "" && *destination != "" {
+		dstPath, err := filepath.Abs(filepath.Dir(*destination))
+		if err != nil {
+			log.Fatalf("Unable to determine destination file path: %v", err)
+		}
+		outputPackagePath, err = parsePackageImport(dstPath)
+		if err != nil {
+			log.Fatalf("Unable to determine destination file path: %v", err)
 		}
 	}
 
@@ -330,7 +328,7 @@
 		}
 
 		// Avoid importing package if source pkg == output pkg
-		if pth == pkg.PkgPath && outputPkgName == pkg.Name {
+		if pth == pkg.PkgPath && outputPackagePath == pkg.PkgPath {
 			continue
 		}