From 5d2ca40d04c9fd2fddc76312ef36f1f16c4fe31c Mon Sep 17 00:00:00 2001 From: Ryan D McGuire Date: Sun, 10 Dec 2023 00:05:39 -0500 Subject: [PATCH] Add cache maintenance locking --- README.md | 4 ++++ cmd/alias_list.go | 3 +-- cmd/cache.go | 6 ++++-- internal/projects/cache.go | 27 +++++++++++++++++++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 0d7448d..812f31e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # GitLab Project Manager +## TODO + +- Fix NPE when cache is reset or project for whatever reason leaves an orphaned alias + ## Purpose The goal of this utility is to provide a fuzzy-find method of locating, cloning, diff --git a/cmd/alias_list.go b/cmd/alias_list.go index 2f9f7c8..e0f0b84 100644 --- a/cmd/alias_list.go +++ b/cmd/alias_list.go @@ -23,8 +23,7 @@ func runListAliasCmd(cmd *cobra.Command, args []string) { WithBoxStyle(&pterm.Style{pterm.FgLightBlue}). WithTitle(pterm.Bold.Sprint(pterm.LightGreen("Aliases by Project"))). Print("\n" + cache.AliasesByProjectString()) - fmt.Println("\n") - // fmt.Print("\n" + cache.AliasesByProjectString() + "\n") + fmt.Print("\n\n") } func init() { diff --git a/cmd/cache.go b/cmd/cache.go index d40f6c0..e4a9429 100644 --- a/cmd/cache.go +++ b/cmd/cache.go @@ -14,16 +14,18 @@ var cacheCmd = &cobra.Command{ Use: "cache", Short: "Manage GitLab project cache", Long: cacheCmdLong, - PersistentPreRun: initCacheCmd, + PersistentPreRun: runCacheCmd, PersistentPostRun: postCacheCmd, } -func initCacheCmd(cmd *cobra.Command, args []string) { +func runCacheCmd(cmd *cobra.Command, args []string) { initProjectCache(cmd, args) + cache.LockCache() } func postCacheCmd(cmd *cobra.Command, args []string) { postProjectCache(cmd, args) + cache.UnlockCache() } func init() { diff --git a/internal/projects/cache.go b/internal/projects/cache.go index 0fbe213..ebc8cdd 100644 --- a/internal/projects/cache.go +++ b/internal/projects/cache.go @@ -51,6 +51,33 @@ func (c *Cache) Load() error { return err } +func (c *Cache) UnlockCache() { + c.log.Info("Unlocking cache") + if err := os.Remove(c.file + ".lock"); err != nil { + c.log.Fatal("Failed unlocking cache, manual rm may be necessary", + c.log.Args("error", err, "lockFile", c.file+".lock"), + ) + } +} + +func (c *Cache) LockCache() { + c.log.Info("Attempting to lock cache") + c.checkLock() + + file, err := os.OpenFile(c.file+".lock", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0640) + defer file.Close() + + if err != nil { + c.log.Fatal("Failed to lock cache", c.log.Args("error", err)) + } +} + +func (c *Cache) checkLock() { + if _, err := os.Stat(c.file + ".lock"); err == nil { + c.log.Fatal("Can't manage cache, already locked") + } +} + // Saves the current state of the cache to disk func (c *Cache) write() { file, err := os.OpenFile(c.file, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0640)