in gomod/module_tree.go [47:112]
func (t *ModuleTree) Insert(modulePath string, attributes ...string) (newNode *ModuleTreeNode, err error) {
moduleRelPath := modulePath
if t.options.RootPath != "" {
moduleRelPath, err = filepath.Rel(t.options.RootPath, modulePath)
if err != nil {
return nil, fmt.Errorf("module %q is not nested within %q, %w",
modulePath, t.options.RootPath, err)
}
}
if m := t.Get(moduleRelPath); m != nil {
return nil, fmt.Errorf("module already exists with relative path, %v, %v",
modulePath, moduleRelPath)
}
// search tree for nodes that have the prefix of this node, when they are
// found walk down to the next layer to find the next node with a more
// specific prefix.
nodes := &t.subModules
for {
var nextNodes *[]*ModuleTreeNode
for _, m := range *nodes {
if m.AncestorOf(moduleRelPath) {
nextNodes = &m.subModules
break
}
}
// Walk the module tree until there is no more direct ancestors. Then
// insert the module at that layer. If the new module is it self an
// ancestor of some other nodes at this layer, re-parent the children
// nodes.
if nextNodes == nil {
// Copy attributes to ensure list cannot be mutated outside of the node.
if len(attributes) != 0 {
attributes = append([]string{}, attributes...)
}
newNode = &ModuleTreeNode{
absPath: modulePath,
relPath: moduleRelPath,
attributes: attributes,
}
// Before adding the new node to the parent, check if there are any
// existing sub modules of this parent have this new node as their
// parent.
for i := 0; i < len(*nodes); i++ {
if !newNode.AncestorOf((*nodes)[i].Path()) {
continue
}
newNode.subModules = append(newNode.subModules, (*nodes)[i])
sort.Sort(sortableModuleTreeNodes(newNode.subModules))
*nodes = cutSubModule(*nodes, i)
i--
}
*nodes = append(*nodes, newNode)
sort.Sort(sortableModuleTreeNodes(*nodes))
return newNode, nil
}
nodes = nextNodes
}
}