diff --git a/Setup b/Setup new file mode 100755 index 0000000..dee5d17 Binary files /dev/null and b/Setup differ diff --git a/confs/repko.yaml b/confs/repko.yaml index d62135f..26d36c8 100644 --- a/confs/repko.yaml +++ b/confs/repko.yaml @@ -455,7 +455,7 @@ sections: field-type: "input" description: "Логин для входа на сайт" validate: - - rule: "regex_match(repko_login,`^[a-zA-Z0-9_-]+$`" + - rule: "regex_match(repko_login,`^[a-zA-Z0-9_-]+$`)" message: "Только строчные латинские буквы, цифры, _, -" - name: "repko pass" variable-name: "repko_pass" @@ -494,6 +494,15 @@ sections: validate: - rule: "dir_exists(archive_root)" message: "Папка не существует" + actions: + - name: "create debian dir" + type: "command" + command: "mkdir -p {{.debian_root}}" + error: "Ошибка создания папки debian" + - name: "create archive dir" + type: "command" + command: "mkdir -p {{.archive_root}}" + error: "Ошибка создания папки archive" - name: "finale" description: "Последний этап, проверьте правильность введенных данных" type: "final" diff --git a/setup/final.go b/setup/final.go index 5e2d35b..c1e1086 100644 --- a/setup/final.go +++ b/setup/final.go @@ -50,6 +50,10 @@ func (m *FinalModel) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case key.Matches(msg, types.MainKeys.Bottom): //Обработчик клавиши перехода на самый верх m.viewport.GotoBottom() + case key.Matches(msg, types.MainKeys.Confirm): + return m, func() tea.Msg { + return types.NextSectionMsg{} + } } case tea.WindowSizeMsg: //Отслеживаем и записываем новые размер окна, вносим изменения в размеры viewport diff --git a/setup/main.go b/setup/main.go index 556a423..6d9f579 100644 --- a/setup/main.go +++ b/setup/main.go @@ -12,7 +12,6 @@ import ( func Start() { //Создаем новый объект Main для настройки. - //todo работа внутри apt, вывод интерфейса во время выполнения apt m := NewMain() p := tea.NewProgram(m, tea.WithAltScreen()) //Запускаем через bubble tea программу m.Program = p //Указываем объекту настроек, программу в которой запущен, чтобы передавать туда сигналы @@ -108,7 +107,7 @@ func (m *Main) Update(msg tea.Msg) (tea.Model, tea.Cmd) { return types.ShowModalMsg{ Type: types.ModalWarning, Title: "Закрытие приложения", - Message: "Вы нажали ctrl+c, вы желаете закрыть приложение?", + Message: "Вы нажали ctrl+c/ctrl+q, вы желаете закрыть приложение?", ModalButtons: []types.ModalButton{ {Text: "Закрыть приложение", Value: true}, {Text: "Не закрывать", Value: false}, @@ -295,7 +294,7 @@ func (m *Main) executeSectionActions() { for _, action := range m.CurrentSection.Actions { //Если условие для действия не выполняется, то пропускаем if !utils.CheckCondition(action.Condition, m.CurrentApplication) { - return + continue } sectionActionLog := fmt.Sprintf("Выполнение действия: %s", action.Name) logrus.Infof(sectionActionLog) @@ -330,6 +329,7 @@ func (m *Main) executeSectionActions() { // NextSectionProcess проверяет доступность следующей секции для настройки func (m *Main) NextSectionProcess() (bool, types.ShowModalMsg) { //Ищем индекс следующей секции, если он остался 0, то следующие секции недоступны. + //Если текущая секция последняя секция, то завершаем настройку. //Возвращаем модальное окно с выходом к списку приложений nextSectionIndex := 0 for sectionIDx := m.CurrentSectionIdx + 1; sectionIDx < len(m.CurrentApplication.Sections); sectionIDx++ { @@ -339,7 +339,22 @@ func (m *Main) NextSectionProcess() (bool, types.ShowModalMsg) { break } } - if nextSectionIndex == 0 { + + if nextSectionIndex == 0 && m.CurrentSectionIdx+1 == len(m.CurrentApplication.Sections) { + return false, types.ShowModalMsg{ + Type: types.ModalInfo, + Title: "Настройка завершена", + Message: "Настройка завершена, нажмите enter чтобы закрыть приложение", + ModalButtons: []types.ModalButton{ + {Text: "Закрыть приложение", Value: true}, + }, + OnResult: func(result any) tea.Cmd { + return func() tea.Msg { + return tea.Quit() + } + }, + } + } else if nextSectionIndex == 0 { return false, types.ShowModalMsg{ Type: types.ModalWarning, Title: "Ошибка секций приложения", diff --git a/setup/utils/actions.go b/setup/utils/actions.go index 111ca70..c509bbe 100644 --- a/setup/utils/actions.go +++ b/setup/utils/actions.go @@ -100,7 +100,7 @@ func RunCommand(cmdStr, runAs string) (string, error) { } var cmd *exec.Cmd if runAs != "" && runAs != "root" { - cmd = exec.Command("su", "-c", cmdStr, runAs) + cmd = exec.Command("sudo", "-u", runAs, "bash", "-c", cmdStr) } else { cmd = exec.Command("bash", "-c", cmdStr) } @@ -142,7 +142,7 @@ func RenderFileTemplate(source, target string, vars map[string]interface{}) erro //В файл помещаем переменные if err = tmpl.Execute(&rendered, vars); err != nil { - return fmt.Errorf("ошибка подстановки значений в шаблон") + return fmt.Errorf("ошибка подстановки значений в шаблон: %v", err) } if _, err = os.Stat(target); err == nil { backup := target + ".bak" + time.Now().Format("20060102-150405") diff --git a/setup/utils/utils.go b/setup/utils/utils.go index fd5ce5e..146169a 100644 --- a/setup/utils/utils.go +++ b/setup/utils/utils.go @@ -255,7 +255,7 @@ func DefineExprCustomFunctions() []expr.Option { return false, fmt.Errorf("file is dir") } if errors.Is(err, fs.ErrNotExist) { - return false, fmt.Errorf("no such directory or file") + return false, nil } else { return false, err } @@ -275,7 +275,7 @@ func DefineExprCustomFunctions() []expr.Option { return false, fmt.Errorf("file is not a dir") } if errors.Is(err, fs.ErrNotExist) { - return false, fmt.Errorf("no such directory or file") + return false, nil } else { return false, err } diff --git a/types/types.go b/types/types.go index 0278f98..cd1a011 100644 --- a/types/types.go +++ b/types/types.go @@ -109,5 +109,5 @@ var MainKeys = MainKeyMap{ Help: key.NewBinding(key.WithKeys("?", "ctrl+h"), key.WithHelp("?/ctrl+h", "help")), Log: key.NewBinding(key.WithKeys("ctrl+l"), key.WithHelp("ctrl+l", "show/hide log window")), Close: key.NewBinding(key.WithKeys("esc"), key.WithHelp("esc", "close")), - Exit: key.NewBinding(key.WithKeys("ctrl+c"), key.WithHelp("ctrl+c", "quit")), + Exit: key.NewBinding(key.WithKeys("ctrl+c", "ctrl+q"), key.WithHelp("ctrl+c/ctrl+q", "quit")), }