|
4 | 4 | "context"
|
5 | 5 | "crypto/sha256"
|
6 | 6 | "encoding/base64"
|
| 7 | + "encoding/json" |
7 | 8 | "fmt"
|
8 | 9 | "io"
|
9 | 10 | "os"
|
@@ -115,6 +116,11 @@ func (b Builder) addToGoMod(ctx context.Context) error {
|
115 | 116 | return err
|
116 | 117 | }
|
117 | 118 |
|
| 119 | + err = b.mergeReplaceDirectives(ctx, plugin.Path) |
| 120 | + if err != nil { |
| 121 | + return err |
| 122 | + } |
| 123 | + |
118 | 124 | continue
|
119 | 125 | }
|
120 | 126 |
|
@@ -162,6 +168,63 @@ func (b Builder) addReplaceDirective(ctx context.Context, plugin *Plugin) error
|
162 | 168 | return nil
|
163 | 169 | }
|
164 | 170 |
|
| 171 | +func (b Builder) mergeReplaceDirectives(ctx context.Context, pluginPath string) error { |
| 172 | + cmd := exec.CommandContext(ctx, "go", "mod", "edit", "-json") |
| 173 | + cmd.Dir = pluginPath |
| 174 | + |
| 175 | + output, err := cmd.CombinedOutput() |
| 176 | + if err != nil { |
| 177 | + b.log.Warnf("%s", string(output)) |
| 178 | + |
| 179 | + return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err) |
| 180 | + } |
| 181 | + |
| 182 | + var goMod struct { |
| 183 | + Replace []struct { |
| 184 | + Old struct{ Path, Version string } |
| 185 | + New struct{ Path, Version string } |
| 186 | + } |
| 187 | + } |
| 188 | + err = json.Unmarshal(output, &goMod) |
| 189 | + if err != nil { |
| 190 | + return fmt.Errorf("unmarshal go mod json: %w", err) |
| 191 | + } |
| 192 | + |
| 193 | + for _, r := range goMod.Replace { |
| 194 | + abs := filepath.Join(pluginPath, r.New.Path) |
| 195 | + stat, err := os.Stat(abs) |
| 196 | + if err != nil { |
| 197 | + return fmt.Errorf("%s: %w", abs, err) |
| 198 | + } |
| 199 | + if stat.IsDir() { |
| 200 | + r.New.Path = filepath.Join(pluginPath, r.New.Path) |
| 201 | + } |
| 202 | + |
| 203 | + replace := fmt.Sprintf("%s=%s", r.Old.Path, r.New.Path) |
| 204 | + if r.Old.Version != "" { |
| 205 | + replace += "@" + r.Old.Version |
| 206 | + } |
| 207 | + if r.New.Version != "" { |
| 208 | + replace += "@" + r.New.Version |
| 209 | + } |
| 210 | + |
| 211 | + cmd := exec.CommandContext(ctx, "go", "mod", "edit", "-replace", replace) |
| 212 | + cmd.Dir = b.repo |
| 213 | + |
| 214 | + output, err := cmd.CombinedOutput() |
| 215 | + if err != nil { |
| 216 | + b.log.Warnf("%s", string(output)) |
| 217 | + |
| 218 | + return fmt.Errorf("%s: %w", strings.Join(cmd.Args, " "), err) |
| 219 | + } |
| 220 | + } |
| 221 | + |
| 222 | + // NOTE(sublee): We don't need to follow nested replace directives because |
| 223 | + // the directives are effective only at the main module. All necessary |
| 224 | + // replacements should be handled at this level. |
| 225 | + return nil |
| 226 | +} |
| 227 | + |
165 | 228 | func (b Builder) goModTidy(ctx context.Context) error {
|
166 | 229 | cmd := exec.CommandContext(ctx, "go", "mod", "tidy")
|
167 | 230 | cmd.Dir = b.repo
|
|
0 commit comments