func addRelativeReplaces()

in cmd/makerelative/main.go [185:258]


func addRelativeReplaces(repoRoot, modulePath string, registry *Registry) error {
	modDir, mod := registry.MustGet(modulePath)

	modDirToRoot, err := filepath.Rel(modDir, repoRoot)
	if err != nil {
		return err
	}

	var toDrop []string
	for _, replace := range mod.Replace {
		if !registry.Has(replace.Old.Path) {
			continue
		}
		toDrop = append(toDrop, replace.Old.Path)
	}

	for _, drop := range toDrop {
		if err := mod.DropReplace(drop, ""); err != nil {
			return err
		}
	}

	seen := make(map[string]struct{})
	var replaces []toReplace
	var toProcess []*modfile.Require
	var req *modfile.Require
	toProcess = append(toProcess, mod.Require...)

	for len(toProcess) > 0 {
		req, toProcess = toProcess[0], toProcess[1:]

		if _, ok := seen[req.Mod.Path]; ok {
			continue
		} else {
			seen[req.Mod.Path] = struct{}{}
		}

		if !registry.Has(req.Mod.Path) {
			continue
		}

		reqDir, reqMod := registry.MustGet(req.Mod.Path)

		reqFromRoot, err := filepath.Rel(repoRoot, reqDir)
		if err != nil {
			return err
		}

		relPathToReq := filepath.Join(modDirToRoot, reqFromRoot)
		if !strings.HasSuffix(relPathToReq, string(filepath.Separator)) {
			relPathToReq += string(filepath.Separator)
		}

		replaces = append(replaces, toReplace{
			ModulePath:   req.Mod.Path,
			RelativePath: relPathToReq,
		})

		toProcess = append(toProcess, reqMod.Require...)
	}

	sort.Slice(replaces, func(i, j int) bool {
		return replaces[i].ModulePath < replaces[j].ModulePath
	})

	for _, replace := range replaces {
		err = mod.AddReplace(replace.ModulePath, "", replace.RelativePath, "")
		if err != nil {
			return err
		}
	}

	return nil
}