@@ -81,6 +81,15 @@ func newBuildEnvironment(b *Builder) (*buildEnvironment, error) {
8181 return env , nil
8282}
8383
84+ // ensureModuleRequired adds a replaced module to go.mod as a requirement.
85+ // Replaced modules need an explicit require directive with a placeholder version,
86+ // otherwise Go reports "replaced but not required" errors during compilation.
87+ func (env * buildEnvironment ) ensureModuleRequired (ctx context.Context , pkg string ) error {
88+ // Strip version suffix if present, use placeholder version for replaced modules.
89+ mod , _ , _ := strings .Cut (pkg , "@" )
90+ return env .execGoMod (ctx , "edit" , "-require" , mod + "@v0.0.0" )
91+ }
92+
8493func (env * buildEnvironment ) CreateModFile (ctx context.Context , opts * BuildOptions ) error {
8594 var err error
8695 // Create go.mod.
@@ -89,47 +98,67 @@ func (env *buildEnvironment) CreateModFile(ctx context.Context, opts *BuildOptio
8998 return err
9099 }
91100
92- // Replace requested modules .
101+ // Apply requested module replacements .
93102 for o , n := range opts .ModReplace {
94103 err = env .execGoMod (ctx , "edit" , "-replace" , o + "=" + n )
95104 if err != nil {
96105 return err
97106 }
98107 }
99108
100- // Download the requested dependencies directly .
109+ // Download dependencies.
101110 if opts .NoCache {
102- domains := make ([]string , len (opts .Plugins ))
103- for i := 0 ; i < len (domains ); i ++ {
104- domains [i ] = opts .Plugins [i ].Path
111+ // Set GONOSUMDB and GONOPROXY for modules that should not be cached or verified.
112+ domains := make ([]string , 0 , len (opts .Plugins )+ 1 )
113+ for _ , p := range opts .Plugins {
114+ domains = append (domains , p .Path )
115+ }
116+ if opts .CorePkg .Path != "" {
117+ domains = append (domains , opts .CorePkg .Path )
105118 }
106119 noproxy := strings .Join (domains , "," )
107120 env .env = append (env .env , "GONOSUMDB=" + noproxy , "GONOPROXY=" + noproxy )
108121 }
109122
110- // Download core.
111- err = env .execGoGet (ctx , opts .CorePkg .String ())
112- if err != nil {
123+ // Download core package.
124+ // Replaced modules need an explicit require directive first, otherwise Go
125+ // reports "replaced but not required" errors during compilation.
126+ if _ , ok := opts .ModReplace [opts .CorePkg .Path ]; ok {
127+ if err = env .ensureModuleRequired (ctx , opts .CorePkg .String ()); err != nil {
128+ return err
129+ }
130+ }
131+ if err = env .execGoGet (ctx , opts .CorePkg .String ()); err != nil {
113132 return err
114133 }
115134
116135 // Download plugins.
117- nextPlugin:
118136 for _ , p := range opts .Plugins {
119- // Do not get plugins of module subpath.
137+ // Skip plugins that are subpaths of replaced modules.
138+ isSubpath := false
120139 for repl := range opts .ModReplace {
121140 if p .Path != repl && strings .HasPrefix (p .Path , repl ) {
122- continue nextPlugin
141+ isSubpath = true
142+ break
123143 }
124144 }
125- err = env .execGoGet (ctx , p .String ())
126- if err != nil {
145+ if isSubpath {
146+ continue
147+ }
148+
149+ // Replaced modules need an explicit require directive before go get.
150+ if _ , ok := opts .ModReplace [p .Path ]; ok {
151+ if err = env .ensureModuleRequired (ctx , p .String ()); err != nil {
152+ return err
153+ }
154+ }
155+ if err = env .execGoGet (ctx , p .String ()); err != nil {
127156 return err
128157 }
129158 }
130159 // @todo update all but with fixed versions if requested
131160
132- return err
161+ return nil
133162}
134163
135164func (env * buildEnvironment ) Filepath (s string ) string {
0 commit comments