From d27d858a71c5ff0000d72d33bd64261f14200ac7 Mon Sep 17 00:00:00 2001 From: Piotr Icikowski Date: Sat, 1 Jan 2022 23:36:42 +0100 Subject: [PATCH] Improve apps update process --- application/cli/cmd_update.go | 135 +++++++++++++++++++++------------- 1 file changed, 85 insertions(+), 50 deletions(-) diff --git a/application/cli/cmd_update.go b/application/cli/cmd_update.go index 3dc5ca5..055f11f 100644 --- a/application/cli/cmd_update.go +++ b/application/cli/cmd_update.go @@ -3,9 +3,9 @@ package cli import ( "fmt" "strings" + "sync" "time" - "github.com/fatih/color" cliv2 "github.com/urfave/cli/v2" "icikowski.pl/myapps/common" "icikowski.pl/myapps/config" @@ -44,67 +44,102 @@ func update(ctx *cliv2.Context) error { fmt.Printf("Processing %s application(s)...\n", common.FmtHeader("%d", len(effectiveApps))) - errorsOcurred := false + outdatedApps := []string{} + conflictApps := map[string]string{} + outdatedAppsMutex, conflictAppsMutex, waitGroup := sync.Mutex{}, sync.Mutex{}, sync.WaitGroup{} + waitGroup.Add(len(effectiveApps)) + for _, appFullName := range effectiveApps { - fmt.Printf("\nProcessing %s...\n", color.BlueString(appFullName)) - splittedAppFullName := strings.Split(appFullName, "/") - repoName, appName := splittedAppFullName[0], splittedAppFullName[1] - - common.BoxInfo.Print("Checking for deployment presence") - deployment, ok := deployments.Find(repoName, appName) - if !ok { - common.BoxWarn.Print("Application is not installed") - continue - } + appFullName := appFullName - common.BoxInfo.Print("Checking for repository presence") - repo, ok := repos.FindByName(repoName) - if !ok { - common.BoxErr.Print("Repository not found") - errorsOcurred = true - continue - } + go func() { + defer waitGroup.Done() - common.BoxInfo.Print("Checking for application presence") - app, ok := repo.Contents.FindByName(appName) - if !ok { - common.BoxErr.Print("Application not found") - errorsOcurred = true - continue - } + splittedAppFullName := strings.Split(appFullName, "/") + repoName, appName := splittedAppFullName[0], splittedAppFullName[1] + + _, ok := deployments.Find(repoName, appName) + if !ok { + conflictAppsMutex.Lock() + conflictApps[appFullName] = "application is not installed" + conflictAppsMutex.Unlock() + return + } + + repo, ok := repos.FindByName(repoName) + if !ok { + conflictAppsMutex.Lock() + conflictApps[appFullName] = "repository not found" + conflictAppsMutex.Unlock() + return + } + + app, ok := repo.Contents.FindByName(appName) + if !ok { + conflictAppsMutex.Lock() + conflictApps[appFullName] = "application not found" + conflictAppsMutex.Unlock() + return + } + + updateAvailable, err := app.IsUpdateAvailable() + if err != nil { + conflictAppsMutex.Lock() + conflictApps[appFullName] = fmt.Sprintf("cannot check update availability: %s", err.Error()) + conflictAppsMutex.Unlock() + return + } + + if updateAvailable { + outdatedAppsMutex.Lock() + outdatedApps = append(outdatedApps, appFullName) + outdatedAppsMutex.Unlock() + } + }() + } + waitGroup.Wait() + + for appFullName, errorMsg := range conflictApps { + fmt.Printf("%s: %s\n", common.FmtHeader(appFullName), errorMsg) + } + + if len(outdatedApps) != 0 { + fmt.Printf("Updating %s application(s)...\n", common.FmtHeader("%d", len(outdatedApps))) + errorsOcurred := false + for _, appFullName := range outdatedApps { + splittedAppFullName := strings.Split(appFullName, "/") + repoName, appName := splittedAppFullName[0], splittedAppFullName[1] + + repo, _ := repos.FindByName(repoName) + app, _ := repo.Contents.FindByName(appName) - common.BoxInfo.Print("Checking for updates") - currentVersion, err := app.GetCurrentVersion() - if err != nil { - common.BoxErr.Print(fmt.Sprintf("Cannot check current version: %s", err.Error())) - errorsOcurred = true - continue - } - latestVersion, err := app.GetLatestVersion() - if err != nil { - common.BoxErr.Print(fmt.Sprintf("Cannot check latest version: %s", err.Error())) - errorsOcurred = true - continue - } - if currentVersion.LessThan(latestVersion) { - common.BoxErr.Print("Newer version is available, updating application") if err := app.Update(); err != nil { - common.BoxErr.Print(fmt.Sprintf("Failed to update application: %s", err.Error())) + common.BoxErr.Print(fmt.Sprintf( + "%s cannot be updated due to error: %s", + common.FmtHeader("%s", app), + err.Error(), + )) errorsOcurred = true continue + } else { + common.BoxSuccess.Print(fmt.Sprintf( + "%s has been updated successfully", + common.FmtHeader("%s", app), + )) } + deployment, _ := deployments.Find(repoName, appName) deployment.UpdatedOn = time.Now() - deployments = deployments.Update(deployment) - common.BoxSuccess.Print("Application updated successfully") - } else { - common.BoxSuccess.Print("Application is already up to date") + deployments.Update(deployment) } - } - config.SetDeployments(deployments) + config.SetDeployments(deployments) - if errorsOcurred { - return common.ExitWithWarnMsg("some applications failed to update") + if errorsOcurred { + return common.ExitWithErrMsg("some applications were not updated") + } + } else { + fmt.Printf("There are no applications that require updates.\n") } + return nil }