X-Git-Url: https://ruderich.org/simon/gitweb/?a=blobdiff_plain;f=remote%2Fsync%2Ftriggers.go;fp=remote%2Fsync%2Ftriggers.go;h=d201835e7e7271b9729da033a409c53b004edce9;hb=9269fa3c94e700afc0be823f58ea473a2db8f3dc;hp=0000000000000000000000000000000000000000;hpb=fd97e8019e2ab166d9475ed59782c86247d8430b;p=safcm%2Fsafcm.git diff --git a/remote/sync/triggers.go b/remote/sync/triggers.go new file mode 100644 index 0000000..d201835 --- /dev/null +++ b/remote/sync/triggers.go @@ -0,0 +1,71 @@ +// MsgSyncReq: run triggers for changed files + +// Copyright (C) 2021 Simon Ruderich +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . + +package sync + +import ( + "path/filepath" + "strings" + + "ruderich.org/simon/safcm" +) + +// queueTriggers queues all triggers applying to file. +func (s *Sync) queueTriggers(file *safcm.File) { + for _, path := range triggerPaths(file.Path) { + if s.req.Files[path].TriggerCommands == nil { + continue + } + // Queue each trigger only once + if s.triggersActive[path] { + s.log.Debugf( + "files: %q: skipping trigger on %q, already active", + file.Path, path) + continue + } + + s.log.Verbosef("files: %q: queuing trigger on %q", + file.Path, path) + s.triggers = append(s.triggers, path) + s.triggersActive[path] = true + } +} + +// triggerPaths returns all possible trigger paths for path, that is the path +// itself and all parent paths. The paths are returned in reverse order so +// more specific triggers can override effects of less specific ones (first +// "/" or ".", then the parents and finally path itself). +func triggerPaths(path string) []string { + sep := string(filepath.Separator) + if path == sep || path == "." { + return []string{path} + } + parts := strings.Split(path, sep) + if strings.HasPrefix(path, sep) { + // Absolute path + parts[0] = sep + } else { + // Relative path + parts = append([]string{"."}, parts...) + } + + var res []string + for i := 0; i < len(parts); i++ { + res = append(res, filepath.Join(parts[:i+1]...)) + } + return res +}