From 7e4b8bb05f2c453a2481930ca48542d73b1e2030 Mon Sep 17 00:00:00 2001 From: Dan Anglin Date: Sat, 17 Aug 2024 21:56:54 +0100 Subject: [PATCH] fix: fixed the calculations in cache directories Changes: - Fixed the issue where the instance's FQDN was not included in the cache directories' path when the user sets a custom path to the root cache directory. - Added unit tests for the cache directory calculations. - Updated REUSE.toml to fix compliance failures. - Added small changes/fixes based on feedback from golangci-lint. PR: https://codeflow.dananglin.me.uk/apollo/enbas/pulls/53 Resolves: https://codeflow.dananglin.me.uk/apollo/enbas/issues/51 --- REUSE.toml | 2 + cmd/enbas-codegen/main.go | 6 +- cmd/enbas/main.go | 2 +- internal/executor/account.go | 2 +- internal/executor/create.go | 10 ++-- internal/executor/delete.go | 11 ++-- internal/executor/show.go | 9 ++- internal/utilities/directories.go | 40 +++++++++++-- internal/utilities/directories_test.go | 78 ++++++++++++++++++++++++++ internal/utilities/helpers_test.go | 16 ++++++ test/cache/.gitkeep | 0 test/config/.gitkeep | 0 12 files changed, 149 insertions(+), 27 deletions(-) create mode 100644 internal/utilities/directories_test.go create mode 100644 internal/utilities/helpers_test.go create mode 100644 test/cache/.gitkeep create mode 100644 test/config/.gitkeep diff --git a/REUSE.toml b/REUSE.toml index ce67f9b..303ed5c 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -15,6 +15,8 @@ path = [ "cmd/enbas-codegen/templates/**/*.go.gotmpl", "schema/enbas_cli_schema.json", ".forgejo/workflows/*.yaml", + ".forgejo/actions/**/action.yaml", + ".forgejo/actions/**/Dockerfile", ] precedence = "override" SPDX-FileCopyrightText = "2024 Dan Anglin " diff --git a/cmd/enbas-codegen/main.go b/cmd/enbas-codegen/main.go index b16e60b..42c127e 100644 --- a/cmd/enbas-codegen/main.go +++ b/cmd/enbas-codegen/main.go @@ -24,11 +24,13 @@ func main() { schema, err := newEnbasCLISchemaFromFile(enbasCLISchemaFilepath) if err != nil { - fmt.Printf("ERROR: Unable to read the schema file: %v.\n", err) + fmt.Fprintf(os.Stderr, "ERROR: Unable to read the schema file: %v.\n", err) + os.Exit(1) } if err := generateExecutors(schema, packageName); err != nil { - fmt.Printf("ERROR: Unable to generate the executors: %v.\n", err) + fmt.Fprintf(os.Stderr, "ERROR: Unable to generate the executors: %v.\n", err) + os.Exit(1) } } diff --git a/cmd/enbas/main.go b/cmd/enbas/main.go index cd1ddd5..3407d92 100644 --- a/cmd/enbas/main.go +++ b/cmd/enbas/main.go @@ -45,5 +45,5 @@ func run() error { command := flag.Arg(0) args := flag.Args()[1:] - return executor.Execute(command, args, noColor, configDir) + return executor.Execute(command, args, noColor, configDir) //nolint:wrapcheck } diff --git a/internal/executor/account.go b/internal/executor/account.go index b7d0f0c..75cc3a6 100644 --- a/internal/executor/account.go +++ b/internal/executor/account.go @@ -79,7 +79,7 @@ func getOtherAccounts(gtsClient *client.Client, accountNames internalFlag.String numAccountNames := len(accountNames) accounts := make([]model.Account, numAccountNames) - for ind := 0; ind < numAccountNames; ind++ { + for ind := range numAccountNames { var err error accounts[ind], err = gtsClient.GetAccount(accountNames[ind]) diff --git a/internal/executor/create.go b/internal/executor/create.go index 10d8367..7f643cd 100644 --- a/internal/executor/create.go +++ b/internal/executor/create.go @@ -99,7 +99,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error { } if descriptionsExists { - for ind := 0; ind < numMediaFiles; ind++ { + for ind := range numMediaFiles { mediaDesc, err := utilities.ReadContents(c.mediaDescriptions[ind]) if err != nil { return fmt.Errorf("unable to read the contents from %s: %w", c.mediaDescriptions[ind], err) @@ -109,7 +109,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error { } } - for ind := 0; ind < numMediaFiles; ind++ { + for ind := range numMediaFiles { var ( mediaFile string description string @@ -156,7 +156,7 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error { preferences, err := gtsClient.GetUserPreferences() if err != nil { - fmt.Println("WARNING: Unable to get your posting preferences: %w", err) + c.printer.PrintInfo("WARNING: Unable to get your posting preferences: " + err.Error() + ".\n") } if c.language != "" { @@ -179,12 +179,12 @@ func (c *CreateExecutor) createStatus(gtsClient *client.Client) error { parsedVisibility, err := model.ParseStatusVisibility(visibility) if err != nil { - return err + return err //nolint:wrapcheck } parsedContentType, err := model.ParseStatusContentType(c.contentType) if err != nil { - return err + return err //nolint:wrapcheck } form := client.CreateStatusForm{ diff --git a/internal/executor/delete.go b/internal/executor/delete.go index 5ddd00f..56246a0 100644 --- a/internal/executor/delete.go +++ b/internal/executor/delete.go @@ -72,13 +72,10 @@ func (d *DeleteExecutor) deleteStatus(gtsClient *client.Client) error { d.printer.PrintSuccess("The status was successfully deleted.") if d.saveText { - cacheDir := filepath.Join( - utilities.CalculateCacheDir( - d.config.CacheDirectory, - utilities.GetFQDN(gtsClient.Authentication.Instance), - ), - "statuses", - ) + cacheDir, err := utilities.CalculateStatusesCacheDir(d.config.CacheDirectory, gtsClient.Authentication.Instance) + if err != nil { + return fmt.Errorf("unable to get the cache directory for the status: %w", err) + } if err := utilities.EnsureDirectory(cacheDir); err != nil { return fmt.Errorf("unable to ensure the existence of the directory %q: %w", cacheDir, err) diff --git a/internal/executor/show.go b/internal/executor/show.go index 2c86c6b..4e8f824 100644 --- a/internal/executor/show.go +++ b/internal/executor/show.go @@ -2,7 +2,6 @@ package executor import ( "fmt" - "path/filepath" "codeflow.dananglin.me.uk/apollo/enbas/internal/client" "codeflow.dananglin.me.uk/apollo/enbas/internal/media" @@ -462,10 +461,10 @@ func (s *ShowExecutor) showMediaFromStatus(gtsClient *client.Client) error { return fmt.Errorf("unable to retrieve the status: %w", err) } - cacheDir := filepath.Join( - utilities.CalculateCacheDir(s.config.CacheDirectory, utilities.GetFQDN(gtsClient.Authentication.Instance)), - "media", - ) + cacheDir, err := utilities.CalculateMediaCacheDir(s.config.CacheDirectory, gtsClient.Authentication.Instance) + if err != nil { + return fmt.Errorf("unable to get the media cache directory: %w", err) + } if err := utilities.EnsureDirectory(cacheDir); err != nil { return fmt.Errorf("unable to ensure the existence of the directory %q: %w", cacheDir, err) diff --git a/internal/utilities/directories.go b/internal/utilities/directories.go index 60b79ae..f3cd194 100644 --- a/internal/utilities/directories.go +++ b/internal/utilities/directories.go @@ -9,6 +9,11 @@ import ( "codeflow.dananglin.me.uk/apollo/enbas/internal" ) +const ( + cacheMediaDir = "media" + cacheStatusesDir = "statuses" +) + func CalculateConfigDir(configDir string) string { if configDir != "" { return configDir @@ -22,17 +27,37 @@ func CalculateConfigDir(configDir string) string { return filepath.Join(configRoot, internal.ApplicationName) } -func CalculateCacheDir(cacheDir, instanceFQDN string) string { - if cacheDir != "" { - return cacheDir +func CalculateMediaCacheDir(cacheRoot, instance string) (string, error) { + cacheDir, err := calculateCacheDir(cacheRoot, instance) + if err != nil { + return "", fmt.Errorf("unable to calculate the cache directory: %w", err) + } + + return filepath.Join(cacheDir, cacheMediaDir), nil +} + +func CalculateStatusesCacheDir(cacheRoot, instance string) (string, error) { + cacheDir, err := calculateCacheDir(cacheRoot, instance) + if err != nil { + return "", fmt.Errorf("unable to calculate the cache directory: %w", err) + } + + return filepath.Join(cacheDir, cacheStatusesDir), nil +} + +func calculateCacheDir(cacheRoot, instance string) (string, error) { + fqdn := GetFQDN(instance) + + if cacheRoot != "" { + return filepath.Join(cacheRoot, fqdn), nil } cacheRoot, err := os.UserCacheDir() if err != nil { - return filepath.Join(os.Getenv("HOME"), "."+internal.ApplicationName, "cache") + return "", fmt.Errorf("unable to get your default cache directory: %w", err) } - return filepath.Join(cacheRoot, internal.ApplicationName, instanceFQDN) + return filepath.Join(cacheRoot, internal.ApplicationName, fqdn), nil } func EnsureDirectory(dir string) error { @@ -42,7 +67,10 @@ func EnsureDirectory(dir string) error { return fmt.Errorf("unable to create %s: %w", dir, err) } } else { - return fmt.Errorf("received an unknown error after getting the directory information: %w", err) + return fmt.Errorf( + "received an unknown error after getting the directory information: %w", + err, + ) } } diff --git a/internal/utilities/directories_test.go b/internal/utilities/directories_test.go new file mode 100644 index 0000000..53e04e7 --- /dev/null +++ b/internal/utilities/directories_test.go @@ -0,0 +1,78 @@ +package utilities_test + +import ( + "path/filepath" + "testing" + + "codeflow.dananglin.me.uk/apollo/enbas/internal/utilities" +) + +func TestCalculateMediaCacheDir(t *testing.T) { + t.Parallel() + + projectDir, err := projectRoot() + if err != nil { + t.Fatalf("Unable to get the project root directory: %v", err) + } + + cacheRoot := filepath.Join(projectDir, "test", "cache") + instance := "http://gotosocial.yellow-desert.social" + + got, err := utilities.CalculateMediaCacheDir(cacheRoot, instance) + if err != nil { + t.Fatalf("Unable to calculate the media cache directory: %v", err) + } + + want := projectDir + "/test/cache/gotosocial.yellow-desert.social/media" + + if got != want { + t.Errorf("Unexpected media cache directory calculated: want %s, got %s", want, got) + } else { + t.Logf("Expected media cache directory calculated: got %s", got) + } +} + +func TestCalculateMediaCacheDirWithXDG(t *testing.T) { + t.Setenv("XDG_CACHE_HOME", "/home/enbas/.cache") + + cacheRoot := "" + instance := "https://gotosocial.yellow-desert.social" + + got, err := utilities.CalculateMediaCacheDir(cacheRoot, instance) + if err != nil { + t.Fatalf("Unable to calculate the media cache directory: %v", err) + } + + want := "/home/enbas/.cache/enbas/gotosocial.yellow-desert.social/media" + + if got != want { + t.Errorf("Unexpected media cache directory calculated: want %s, got %s", want, got) + } else { + t.Logf("Expected media cache directory calculated: got %s", got) + } +} + +func TestCalculateStatusesCacheDir(t *testing.T) { + t.Parallel() + + projectDir, err := projectRoot() + if err != nil { + t.Fatalf("Unable to get the project root directory: %v", err) + } + + cacheRoot := filepath.Join(projectDir, "test", "cache") + instance := "https://fedi.blue-mammoth.party" + + got, err := utilities.CalculateStatusesCacheDir(cacheRoot, instance) + if err != nil { + t.Fatalf("Unable to calculate the statuses cache directory: %v", err) + } + + want := projectDir + "/test/cache/fedi.blue-mammoth.party/statuses" + + if got != want { + t.Errorf("Unexpected statuses cache directory calculated: want %s, got %s", want, got) + } else { + t.Logf("Expected statuses cache directory calculated: got %s", got) + } +} diff --git a/internal/utilities/helpers_test.go b/internal/utilities/helpers_test.go new file mode 100644 index 0000000..89c35d7 --- /dev/null +++ b/internal/utilities/helpers_test.go @@ -0,0 +1,16 @@ +package utilities_test + +import ( + "fmt" + "os" + "path/filepath" +) + +func projectRoot() (string, error) { + cwd, err := os.Getwd() + if err != nil { + return "", fmt.Errorf("unable to get the current working directory, %w", err) + } + + return filepath.Join(cwd, "..", ".."), nil +} diff --git a/test/cache/.gitkeep b/test/cache/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/test/config/.gitkeep b/test/config/.gitkeep new file mode 100644 index 0000000..e69de29