1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2024-12-12 13:30:26 +00:00
mycorrhiza/shroom/rename.go

107 lines
3.2 KiB
Go
Raw Normal View History

2021-02-20 14:03:54 +00:00
package shroom
2021-02-17 18:41:35 +00:00
import (
"errors"
"fmt"
"regexp"
"github.com/bouncepaw/mycorrhiza/history"
2021-02-20 14:03:54 +00:00
"github.com/bouncepaw/mycorrhiza/hyphae"
2021-02-17 18:41:35 +00:00
"github.com/bouncepaw/mycorrhiza/user"
"github.com/bouncepaw/mycorrhiza/util"
)
2021-02-20 14:03:54 +00:00
func canRenameThisToThat(oh *hyphae.Hypha, nh *hyphae.Hypha, u *user.User) (err error, errtitle string) {
2021-02-17 18:41:35 +00:00
if nh.Exists {
rejectRenameLog(oh, u, fmt.Sprintf("name %s taken already", nh.Name))
return errors.New(fmt.Sprintf("Hypha named <a href='/hypha/%[1]s'>%[1]s</a> already exists, cannot rename", nh.Name)), "Name taken"
}
if nh.Name == "" {
rejectRenameLog(oh, u, "no new name given")
return errors.New("No new name is given"), "No name given"
}
2021-02-20 14:03:54 +00:00
if !hyphae.HyphaPattern.MatchString(nh.Name) {
2021-02-17 18:41:35 +00:00
rejectRenameLog(oh, u, fmt.Sprintf("new name %s invalid", nh.Name))
return errors.New("Invalid new name. Names cannot contain characters <code>^?!:#@&gt;&lt;*|\"\\'&amp;%</code>"), "Invalid name"
}
return nil, ""
}
// RenameHypha renames hypha from old name `hyphaName` to `newName` and makes a history record about that. If `recursive` is `true`, its subhyphae will be renamed the same way.
2021-02-20 14:03:54 +00:00
func RenameHypha(h *hyphae.Hypha, newHypha *hyphae.Hypha, recursive bool, u *user.User) (hop *history.HistoryOp, errtitle string) {
2021-02-17 18:41:35 +00:00
newHypha.Lock()
defer newHypha.Unlock()
hop = history.Operation(history.TypeRenameHypha)
2021-02-20 14:03:54 +00:00
if err, errtitle := CanRename(u, h); errtitle != "" {
2021-02-26 16:43:45 +00:00
hop.WithErrAbort(err)
2021-02-17 18:41:35 +00:00
return hop, errtitle
}
if err, errtitle := canRenameThisToThat(h, newHypha, u); errtitle != "" {
2021-02-26 16:43:45 +00:00
hop.WithErrAbort(err)
2021-02-17 18:41:35 +00:00
return hop, errtitle
}
var (
re = regexp.MustCompile(`(?i)` + h.Name)
replaceName = func(str string) string {
return re.ReplaceAllString(util.CanonicalName(str), newHypha.Name)
}
hyphaeToRename = findHyphaeToRename(h, recursive)
renameMap, err = renamingPairs(hyphaeToRename, replaceName)
renameMsg = "Rename %s to %s"
)
if err != nil {
hop.Errs = append(hop.Errs, err)
return hop, hop.FirstErrorText()
}
if recursive && len(hyphaeToRename) > 0 {
renameMsg += " recursively"
}
hop.WithFilesRenamed(renameMap).
WithMsg(fmt.Sprintf(renameMsg, h.Name, newHypha.Name)).
WithUser(u).
Apply()
if len(hop.Errs) == 0 {
for _, h := range hyphaeToRename {
2021-02-20 14:03:54 +00:00
h.RenameTo(replaceName(h.Name))
2021-02-20 06:48:27 +00:00
h.Lock()
h.TextPath = replaceName(h.TextPath)
h.BinaryPath = replaceName(h.BinaryPath)
h.Unlock()
2021-02-17 18:41:35 +00:00
}
}
return hop, ""
}
2021-02-20 14:03:54 +00:00
func findHyphaeToRename(superhypha *hyphae.Hypha, recursive bool) []*hyphae.Hypha {
hyphae := []*hyphae.Hypha{superhypha}
2021-02-17 18:41:35 +00:00
if recursive {
hyphae = append(hyphae, superhypha.Subhyphae()...)
}
return hyphae
}
2021-02-20 14:03:54 +00:00
func renamingPairs(hyphaeToRename []*hyphae.Hypha, replaceName func(string) string) (map[string]string, error) {
2021-02-17 18:41:35 +00:00
renameMap := make(map[string]string)
newNames := make([]string, len(hyphaeToRename))
for _, h := range hyphaeToRename {
2021-03-02 16:36:57 +00:00
h.Lock()
2021-02-17 18:41:35 +00:00
newNames = append(newNames, replaceName(h.Name))
if h.TextPath != "" {
renameMap[h.TextPath] = replaceName(h.TextPath)
}
if h.BinaryPath != "" {
renameMap[h.BinaryPath] = replaceName(h.BinaryPath)
}
2021-03-02 16:36:57 +00:00
h.Unlock()
2021-02-17 18:41:35 +00:00
}
2021-02-20 14:03:54 +00:00
if firstFailure, ok := hyphae.AreFreeNames(newNames...); !ok {
2021-02-17 18:41:35 +00:00
return nil, errors.New("Hypha " + firstFailure + " already exists")
}
return renameMap, nil
}