package app import ( "errors" "os" "gitlab.com/revalus/grm/commands" "gitlab.com/revalus/grm/config" ) const ( APP_NAME = "Git repository manager" APP_DESCRIPTION = "Manage your repository with simple app" VERSION = "0.3.0" errNotFoundTags = "no repository was found with the specified tags" errNotFoundName = "no repository was found with the specified name" ) type GitRepositoryManager struct { cliArguments config.CliArguments configuration config.Configuration console ConsoleOutput } func (g *GitRepositoryManager) Parse(args []string) { co := ConsoleOutput{} checkCriticalError := func(err error) { if err != nil { co.ErrorfMsg("%v", err.Error()) os.Exit(2) } } arguments, err := config.ParseCliArguments(APP_NAME, APP_DESCRIPTION, args) checkCriticalError(err) configFileContent, err := getFileContent(arguments.ConfigurationFile) checkCriticalError(err) fileExcension, err := getFileExcension(arguments.ConfigurationFile) checkCriticalError(err) configuration, err := config.GetRepositoryConfig(configFileContent, fileExcension) checkCriticalError(err) co.Color = arguments.Color g.console = co g.cliArguments = arguments g.configuration = configuration } func (g *GitRepositoryManager) Run() int { exitCode := 0 if len(g.cliArguments.LimitTags) != 0 { err := g.limitTags() if err != nil { g.console.ErrorfMsg(err.Error()) exitCode = 1 } } if g.cliArguments.LimitName != "" { err := g.limitName() if err != nil { g.console.ErrorfMsg(err.Error()) exitCode = 1 } } if g.cliArguments.Sync && exitCode == 0 { g.console.InfoFMsg("Synchronizing repositories") sync := commands.NewSynchronizer(g.configuration.Workspace) g.runCommand(sync) g.console.InfoFMsg("All repositories are synced") } if g.cliArguments.Status && exitCode == 0 { g.console.InfoFMsg("Current status of repositories") status := commands.NewStatusChecker(g.configuration.Workspace) g.runCommand(status) } if g.cliArguments.Version { g.console.InfoFMsg("Current version: %v", VERSION) } return exitCode } func (g GitRepositoryManager) describeStatus(status commands.CommandStatus) { if status.Error { g.console.ErrorStatusF("Repository \"%v\": an error occurred: %v", status.Name, status.Message) return } if status.Changed { g.console.ChangedStatusF("Repository \"%v\": %v", status.Name, status.Message) } else { g.console.UnchangedStatusF("Repository \"%v\": %v", status.Name, status.Message) } } func (g *GitRepositoryManager) limitTags() error { limitedTagsTmp := []config.RepositoryConfig{} for _, item := range g.configuration.Repositories { if checkAnyOfItemInSlice(item.Tags, g.cliArguments.LimitTags) { limitedTagsTmp = append(limitedTagsTmp, item) } } if len(limitedTagsTmp) == 0 { return errors.New(errNotFoundTags) } g.configuration.Repositories = reverseRepositoryConfigs(limitedTagsTmp) return nil } func (g *GitRepositoryManager) limitName() error { for _, item := range g.configuration.Repositories { if g.cliArguments.LimitName == item.Name { g.configuration.Repositories = []config.RepositoryConfig{item} return nil } } return errors.New(errNotFoundName) } func (g *GitRepositoryManager) runCommand(cmd commands.Command) { statusChan := make(chan commands.CommandStatus) for _, repo := range g.configuration.Repositories { go cmd.Command(repo, statusChan) } for range g.configuration.Repositories { g.describeStatus(<-statusChan) } }