abak-flow 1.0.10 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/README.md +49 -34
- data/abak-flow.gemspec +1 -3
- data/lib/abak-flow.rb +18 -14
- data/lib/abak-flow/branch.rb +9 -10
- data/lib/abak-flow/commands/checkup.rb +11 -14
- data/lib/abak-flow/commands/compare.rb +14 -24
- data/lib/abak-flow/commands/configure.rb +108 -0
- data/lib/abak-flow/commands/done.rb +80 -0
- data/lib/abak-flow/commands/publish.rb +62 -0
- data/lib/abak-flow/configuration.rb +66 -43
- data/lib/abak-flow/errors_presenter.rb +31 -0
- data/lib/abak-flow/inspector.rb +36 -0
- data/lib/abak-flow/locale.rb +45 -0
- data/lib/abak-flow/locales/en.yml +78 -40
- data/lib/abak-flow/locales/ru.yml +78 -40
- data/lib/abak-flow/manager.rb +28 -8
- data/lib/abak-flow/pull_request.rb +21 -30
- data/lib/abak-flow/repository.rb +17 -32
- data/lib/abak-flow/request.rb +18 -80
- data/lib/abak-flow/version.rb +1 -1
- data/spec/lib/abak-flow/commands/checkup_spec.rb +7 -7
- data/spec/lib/abak-flow/commands/compare_spec.rb +9 -8
- metadata +41 -76
- data/lib/abak-flow/visitor.rb +0 -63
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OGQyNTgyODI5NjI1MTVmMTg2NzQ3OTUwYjM4NTJkNDlmMWYyNzk2Mg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Mjk5YmQ0NjY2ZGM4ZmZlMWJiODY1OTRkYmMwNjM3MGQyYjNlMTJmNg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MWFjNzFjYTM0MGZhMTMyNDU5N2E2NDQ1MWM4YzczNmM4NGY2MzdkOGU3YTUy
|
10
|
+
NDFhYTkwNWQ1NThkN2I3MTJhMzdmMDU0YjFiNWUzZmI0NjExYjA2NWExODBh
|
11
|
+
YmQwNTAyNDg5MzRiNDdhYzRkMmE5NTc0MzZmZjMxZDE0YjkwMDk=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MDA0NjU4NmJlZjFlZTMwMGYxODMyN2IzMWYzYjYwM2JiZTYxOWMxNmQ5NWUx
|
14
|
+
NDI1YmFlNzEzZjVkN2Q3ZWY0YmY5MDM0M2MyOWRkZmEzNDVlY2QzNWI1ODVi
|
15
|
+
ODU4YTJmNTQ2OTQ0M2Y1OWJlNDc2NWFkYTYzY2NkZmE3YjkzODA=
|
data/README.md
CHANGED
@@ -1,40 +1,27 @@
|
|
1
1
|
Abak-flow
|
2
2
|
=========
|
3
|
-
Нет, это не новая идеология ведения проекта, это всего лишь набор утилит которые помогают связать использование [git-flow](https://github.com/nvie/gitflow) и [github flow](http://scottchacon.com/2011/08/31/github-flow.html)
|
4
3
|
|
5
|
-
|
6
|
-
|
7
|
-
**Начиная с версии v1.0.0 используется новый формат конфигурации. [Как мигрировать старую?](https://github.com/Strech/abak-flow/wiki/How-start-work-with-abak-flow-v1.0.0)**
|
8
|
-
|
9
|
-
# Концепция
|
10
|
-
Идеология git-flow использует следующий набор веток:
|
11
|
-
|
12
|
-
* *master* - всегда пригодна для развертывания
|
13
|
-
* *develop* - основная ветка разработки
|
14
|
-
* *hotfix* - ветка для изменений которые попадут на продакшен сервер
|
15
|
-
* *feature* - ветки для крупных задач
|
4
|
+
[![Code Climate](https://codeclimate.com/github/Strech/abak-flow/badges/gpa.svg)](https://codeclimate.com/github/Strech/abak-flow)
|
5
|
+
[![Dependency Status](https://gemnasium.com/Strech/abak-flow.svg)](https://gemnasium.com/Strech/abak-flow)
|
16
6
|
|
17
|
-
|
7
|
+
Нет, это не новая идеология ведения разработки в проекте, это всего лишь набор утилит которые помогают связать использование [git-flow](https://github.com/nvie/gitflow) и [github flow](http://scottchacon.com/2011/08/31/github-flow.html)
|
18
8
|
|
19
|
-
|
9
|
+
**Начиная с версии v0.2.1 используется авторизация OAuth2. [Как ей пользоваться?](https://github.com/Strech/abak-flow/wiki/How-start-work-with-new-abak-flow)**
|
20
10
|
|
21
|
-
|
22
|
-
2. Разработаный функционал из ветки **feature** оформляется pull request только в ветку **develop**
|
23
|
-
3. Все исправления ошибок, которые должны попасть на продакшен сервер делаются только в ветках **hotfix**
|
24
|
-
4. Исправленные ошибки из ветки **hotfix** фофрмляются pull request только в ветку **master**
|
25
|
-
5. После получения исправлений на текущий момент в репозитории инициируется merge ветки **master** в **develop**
|
11
|
+
**Начиная с версии v1.0.0 используется новый формат конфигурации. [Как мигрировать старую?](https://github.com/Strech/abak-flow/wiki/How-start-work-with-abak-flow-v1.0.0)**
|
26
12
|
|
13
|
+
**Начиная с версии v1.1.0 используется новый формат токена для Github API. [Как обновить?](https://github.com/Strech/abak-flow/wiki/How-start-work-with-abak-flow-v1.1.0)**
|
27
14
|
|
28
15
|
# Установка
|
29
16
|
|
30
|
-
$ gem install abak-flow -v 1.
|
17
|
+
$ gem install abak-flow -v '>= 1.1.0'
|
31
18
|
$ git config --global alias.request '!request'
|
32
|
-
$ git
|
33
|
-
$ git config --global abak-flow.oauth-token 0123456789YOUR_GITHUB_API_TOKEN
|
19
|
+
$ git request configure
|
34
20
|
$ git remote add upstream git://github.com/GITHUB_PROJECT_USER/GITHUB_PROJECT_NAME.git
|
35
21
|
|
36
22
|
### А если я использую прокси, как быть?
|
37
|
-
|
23
|
+
|
24
|
+
При конфигурации вас спросят о прокси сервере. Если его нет, оставьте поле пустым
|
38
25
|
|
39
26
|
Далее по приоритету идут переменные окружения. Сначала **http_proxy**, затем **HTTP_PROXY**
|
40
27
|
|
@@ -42,9 +29,11 @@ Github-flow же наоборот ведет основную разработк
|
|
42
29
|
|
43
30
|
---
|
44
31
|
|
45
|
-
|
32
|
+
**Важно:** Пароль никогда и нигде не будет сохранен. Он [будет использован](https://developer.github.com/v3/#basic-authentication) для создания персонального токена
|
33
|
+
|
34
|
+
**Заметьте:** При конфигурации необходимо указать email адрес под которым вы заходите на github
|
46
35
|
|
47
|
-
**Обратите внимание:** В данном контексте под **upstream** подразумевается адрес репозитория в который будут оформляться
|
36
|
+
**Обратите внимание:** В данном контексте под **upstream** подразумевается адрес репозитория в который будут оформляться пул реквесты. А репозиторием **origin** будет являться ваш форк
|
48
37
|
|
49
38
|
# С чего начать?
|
50
39
|
|
@@ -54,35 +43,61 @@ Github-flow же наоборот ведет основную разработк
|
|
54
43
|
|
55
44
|
$ git request help
|
56
45
|
|
57
|
-
**Примечание:** Вообще-то все комманды поддерживают опцию
|
46
|
+
**Примечание:** Вообще-то все комманды поддерживают опцию `--help`, но вот именно `git request --help` успевает перехватиться самим git и он конечно неодумевает как ему показать хэлп по внешней комманде
|
47
|
+
|
48
|
+
# Список команд
|
49
|
+
|
50
|
+
$ git request configure
|
51
|
+
$ git request checkup
|
52
|
+
$ git request compare [--base <имя ветки>] [--head <имя ветки>]
|
53
|
+
$ git request publish [--base <имя ветки>] [--head <имя ветки>] [--title <заголовок>] [--body <описание>]
|
54
|
+
$ git request done
|
55
|
+
|
56
|
+
# Концепция
|
57
|
+
Идеология git-flow использует следующий набор веток:
|
58
|
+
|
59
|
+
* *master* - всегда пригодна для развертывания
|
60
|
+
* *develop* - основная ветка разработки
|
61
|
+
* *hotfix* - ветка для изменений которые попадут на продакшен сервер
|
62
|
+
* *feature* - ветки для крупных задач
|
63
|
+
|
64
|
+
Github-flow же наоборот ведет основную разработку в ветке master, но при этом master является пригодным для развертывания в любой момент.
|
65
|
+
|
66
|
+
После долгих раздумий было принято применить следующий набор правил, для разработки на github:
|
67
|
+
|
68
|
+
1. Вся разработка любой задачи и функционала ведется только в ветках **feature**
|
69
|
+
2. Разработаный функционал из ветки **feature** оформляется pull request только в ветку **develop**
|
70
|
+
3. Все исправления ошибок, которые должны попасть на продакшен сервер делаются только в ветках **hotfix**
|
71
|
+
4. Исправленные ошибки из ветки **hotfix** фофрмляются pull request только в ветку **master**
|
72
|
+
5. После получения исправлений на текущий момент в репозитории инициируется merge ветки **master** в **develop**
|
58
73
|
|
59
74
|
# Примеры использования
|
60
75
|
### Самый простой способ начать новую задачу:
|
61
76
|
|
62
77
|
$ git checkout develop
|
63
|
-
$ git
|
78
|
+
$ git checkout -b feature/TASK-001
|
64
79
|
$ touch 'hello.txt' && echo 'Hello world!' > hello.txt
|
65
80
|
$ git commit -a -m 'Hello world commit'
|
66
81
|
$ git request publish
|
67
82
|
|
68
|
-
**Внимание:** Не нужно называться ветку TASK. Используйте префикс
|
83
|
+
**Внимание:** Не нужно называться ветку TASK. Используйте префикс задач из jira
|
69
84
|
|
70
85
|
Теперь то же самое, только словами:
|
71
86
|
|
72
87
|
* Переключимся в ветку develop
|
73
|
-
*
|
88
|
+
* Создадим ветку в которй будем выполнять задачу
|
74
89
|
* Простое создание нового файла
|
75
|
-
* Git процедуры добавления своих изменений в
|
76
|
-
* Затем публикация вашей ветки на вашем форке (если таковая уже есть, то просто обновление), затем оформление
|
90
|
+
* Git процедуры добавления своих изменений в индекс
|
91
|
+
* Затем публикация вашей ветки на вашем форке (если таковая уже есть, то просто обновление), затем оформление пул реквеста из этой ветки в соответствующую правилам ветку на upstream (в данном случае это будет ветка develop)
|
77
92
|
|
78
93
|
Для задач, которые должны быть выполнены в виде hotfix принцип тот же:
|
79
94
|
|
80
95
|
$ git checkout master
|
81
|
-
$ git
|
96
|
+
$ git checkout -b hotfix/TASK-001
|
82
97
|
$ …
|
83
98
|
$ git request publish
|
84
99
|
|
85
|
-
*На самом деле переключаться на master или develop в самом начале вовсе не обязательно, этот шаг был приведен для
|
100
|
+
*На самом деле переключаться на master или develop в самом начале вовсе не обязательно, этот шаг был приведен для ясности*
|
86
101
|
|
87
102
|
## Маленькие хитрости
|
88
103
|
Если сразу правильно именовать ветки, т.е ветку с задачей создавать с именем, такого формата TASK-001, то, в описание pull request автоматически вставится ссылка на задачу в jira, а в имя pull request сразу вставится название, состоящее из имени задачи, т.е TASK-001
|
@@ -99,4 +114,4 @@ Github-flow же наоборот ведет основную разработк
|
|
99
114
|
|
100
115
|
## Лицензия
|
101
116
|
|
102
|
-
Abak-flow выпускается под лицензией [MIT](http://www.opensource.org/licenses/MIT).
|
117
|
+
Abak-flow выпускается под лицензией [MIT](http://www.opensource.org/licenses/MIT).
|
data/abak-flow.gemspec
CHANGED
@@ -20,15 +20,13 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
21
|
gem.require_paths = ["lib"]
|
22
22
|
|
23
|
-
gem.add_runtime_dependency "octokit", "~> 1.
|
23
|
+
gem.add_runtime_dependency "octokit", "~> 3.1.0"
|
24
24
|
gem.add_runtime_dependency "git", "~> 1.2.5"
|
25
25
|
gem.add_runtime_dependency "commander", "~> 4.1.6"
|
26
26
|
gem.add_runtime_dependency "ruler", "~> 1.4.2"
|
27
27
|
gem.add_runtime_dependency "i18n", "~> 0.6.9"
|
28
28
|
gem.add_runtime_dependency "ansi", "~> 1.4.3"
|
29
29
|
|
30
|
-
gem.add_runtime_dependency "faraday", "= 0.8.9" # TODO : remove after octokit upgrade
|
31
|
-
|
32
30
|
gem.add_development_dependency "cane"
|
33
31
|
gem.add_development_dependency "simplecov"
|
34
32
|
gem.add_development_dependency "rspec", "~> 2.14"
|
data/lib/abak-flow.rb
CHANGED
@@ -1,23 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
require "ansi/code"
|
4
|
+
require "commander/blank"
|
5
|
+
require "commander/command"
|
6
|
+
|
7
|
+
module Abak
|
8
|
+
module Flow
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
1
12
|
require "abak-flow/version"
|
13
|
+
require "abak-flow/locale"
|
2
14
|
require "abak-flow/manager"
|
3
15
|
require "abak-flow/configuration"
|
4
16
|
require "abak-flow/repository"
|
5
17
|
require "abak-flow/branch"
|
6
18
|
require "abak-flow/pull_request"
|
7
|
-
require "abak-flow/
|
19
|
+
require "abak-flow/inspector"
|
20
|
+
require "abak-flow/errors_presenter"
|
8
21
|
require "abak-flow/commands/checkup"
|
9
22
|
require "abak-flow/commands/compare"
|
23
|
+
require "abak-flow/commands/configure"
|
24
|
+
require "abak-flow/commands/publish"
|
25
|
+
require "abak-flow/commands/done"
|
10
26
|
|
11
|
-
|
12
|
-
# Может пригодится
|
13
|
-
# module ::Faraday
|
14
|
-
# class Response::RaiseOctokitError < Response::Middleware
|
15
|
-
# def error_message_with_trace(response)
|
16
|
-
# message = (response[:body].errors || []).map {|error| "=> #{error.code}: #{error.message}" }.join("\n")
|
17
|
-
|
18
|
-
# [error_message_without_trace(response), message].reject { |m| m.empty? }.join("\n\nДополнительные сообщения:\n")
|
19
|
-
# end
|
20
|
-
# alias_method :error_message_without_trace, :error_message
|
21
|
-
# alias_method :error_message, :error_message_with_trace
|
22
|
-
# end
|
23
|
-
# end
|
27
|
+
Abak::Flow::Manager.locale
|
data/lib/abak-flow/branch.rb
CHANGED
@@ -20,9 +20,8 @@ module Abak::Flow
|
|
20
20
|
attr_reader :task
|
21
21
|
|
22
22
|
def initialize(branch)
|
23
|
-
@manager = Manager.instance
|
24
23
|
@branch = branch.is_a?(Git::Branch) ? branch
|
25
|
-
:
|
24
|
+
: Manager.git.branch(branch)
|
26
25
|
|
27
26
|
parse_branch_name
|
28
27
|
end
|
@@ -43,11 +42,11 @@ module Abak::Flow
|
|
43
42
|
end
|
44
43
|
|
45
44
|
def compare_link(branch)
|
46
|
-
diff = "#{
|
45
|
+
diff = "#{Manager.repository.upstream.owner}:#{branch}...#{@branch}"
|
47
46
|
|
48
47
|
File.join [
|
49
|
-
|
50
|
-
|
48
|
+
Manager.github.web_endpoint,
|
49
|
+
Manager.repository.origin.to_s,
|
51
50
|
"compare", diff
|
52
51
|
]
|
53
52
|
end
|
@@ -72,13 +71,13 @@ module Abak::Flow
|
|
72
71
|
end
|
73
72
|
|
74
73
|
def update
|
75
|
-
origin =
|
76
|
-
|
74
|
+
origin = Manager.repository.origin.repo
|
75
|
+
Manager.git.push(origin, @branch)
|
77
76
|
end
|
78
77
|
|
79
78
|
def delete_on_remote
|
80
|
-
origin =
|
81
|
-
|
79
|
+
origin = Manager.repository.origin.repo
|
80
|
+
Manager.git.push(origin, ":#{@branch}")
|
82
81
|
end
|
83
82
|
|
84
83
|
def delete_on_local
|
@@ -114,7 +113,7 @@ module Abak::Flow
|
|
114
113
|
end
|
115
114
|
|
116
115
|
def valid?
|
117
|
-
!@branch.name.empty?
|
116
|
+
!@branch.name.strip.empty?
|
118
117
|
end
|
119
118
|
|
120
119
|
private
|
@@ -1,27 +1,24 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
require "ansi/code"
|
3
|
-
|
4
2
|
module Abak::Flow
|
5
3
|
module Commands
|
6
4
|
class Checkup
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
manager = Manager.instance
|
10
|
-
|
11
|
-
@configuration = manager.configuration
|
12
|
-
@repository = manager.repository
|
13
|
-
end
|
5
|
+
include ANSI::Code
|
14
6
|
|
15
7
|
def run(args, options)
|
16
8
|
process(args, options)
|
17
|
-
|
9
|
+
|
10
|
+
say green { Manager.locale.success(self) }
|
18
11
|
end
|
19
12
|
|
20
13
|
def process(args, options)
|
21
|
-
|
22
|
-
|
23
|
-
|
14
|
+
inspector = Inspector.new(call_method: :valid?, collect_attribute: :errors)
|
15
|
+
inspector.examine(Manager.configuration, Manager.repository).on_fail do |insp|
|
16
|
+
say red { Manager.locale.error(self) }
|
17
|
+
say yellow { insp.output }
|
18
|
+
|
19
|
+
exit 100
|
20
|
+
end
|
24
21
|
end
|
25
22
|
end # class Checkup
|
26
23
|
end # module Commands
|
27
|
-
end # module Abak::Flow
|
24
|
+
end # module Abak::Flow
|
@@ -1,45 +1,35 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
|
3
|
-
require "commander/command"
|
4
|
-
require "ansi/code"
|
2
|
+
# 101 exit code available
|
5
3
|
|
6
4
|
module Abak::Flow
|
7
5
|
module Commands
|
8
6
|
class Compare
|
9
|
-
|
10
|
-
|
11
|
-
def initialize
|
12
|
-
manager = Manager.instance
|
13
|
-
|
14
|
-
@configuration = manager.configuration
|
15
|
-
@repository = manager.repository
|
16
|
-
@git = manager.git
|
17
|
-
end
|
7
|
+
include ANSI::Code
|
18
8
|
|
19
9
|
def run(args, options)
|
20
|
-
Checkup.new.process(
|
21
|
-
Array.new, ::Commander::Command::Options.new)
|
10
|
+
Checkup.new.process(Array.new, ::Commander::Command::Options.new)
|
22
11
|
|
23
|
-
current =
|
12
|
+
current = Manager.git.current_branch
|
24
13
|
head = Branch.new(options.head || current)
|
25
14
|
base = Branch.new(options.base || head.extract_base_name)
|
26
15
|
|
27
16
|
if head.current?
|
28
|
-
say
|
29
|
-
|
30
|
-
branch:
|
31
|
-
upstream:
|
17
|
+
say white {
|
18
|
+
Manager.locale.word(self, 'updating',
|
19
|
+
branch: bold { head },
|
20
|
+
upstream: bold { "#{Manager.repository.origin}" })
|
21
|
+
}
|
32
22
|
|
33
23
|
head.update
|
34
24
|
else
|
35
|
-
say
|
36
|
-
|
37
|
-
|
25
|
+
say yellow {
|
26
|
+
Manager.locale.word(self, 'diverging', branch: bold { head })
|
27
|
+
}
|
38
28
|
end
|
39
29
|
|
40
|
-
say
|
30
|
+
say green { head.compare_link(base) }
|
41
31
|
end
|
42
32
|
|
43
33
|
end
|
44
34
|
end
|
45
|
-
end
|
35
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
require "octokit"
|
3
|
+
|
4
|
+
module Abak::Flow
|
5
|
+
module Commands
|
6
|
+
class Configure
|
7
|
+
include ANSI::Code
|
8
|
+
|
9
|
+
def run(args, options)
|
10
|
+
process(args, options)
|
11
|
+
|
12
|
+
puts
|
13
|
+
say green { Manager.locale.success(self) }
|
14
|
+
end
|
15
|
+
|
16
|
+
def process(args, options)
|
17
|
+
interview
|
18
|
+
|
19
|
+
password_hash = deffered do
|
20
|
+
client = Octokit::Client.new(login: @login, password: @password)
|
21
|
+
response = client.create_authorization(
|
22
|
+
scopes: ["repo"], note: "abak-flow",
|
23
|
+
note_url: "https://github.com/Strech/abak-flow",
|
24
|
+
headers: @headers)
|
25
|
+
|
26
|
+
response[:token]
|
27
|
+
end
|
28
|
+
|
29
|
+
Manager.configuration.rewrite(
|
30
|
+
login: @login, password: password_hash,
|
31
|
+
locale: @locale, http_proxy: @http_proxy)
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
def interview
|
37
|
+
@login = ask("#{Manager.locale.word(self, 'email')}: ")
|
38
|
+
@password = password("#{Manager.locale.word(self, 'password')}: ", nil)
|
39
|
+
@locale = choose("#{Manager.locale.word(self, 'locale')}:\n", :en, :ru)
|
40
|
+
@http_proxy = ask("#{Manager.locale.word(self, 'http_proxy')}: ")
|
41
|
+
@headers = {}
|
42
|
+
end
|
43
|
+
|
44
|
+
def otp_interview
|
45
|
+
@headers = {"X-GitHub-OTP" => ask("#{Manager.locale.word(self, 'sms_otp')}: ")}
|
46
|
+
end
|
47
|
+
|
48
|
+
# TODO : Refactor to object
|
49
|
+
def deffered(&block)
|
50
|
+
progressbar.show
|
51
|
+
thread = Thread.new do
|
52
|
+
Thread.current[:result] = suppress { block.call }
|
53
|
+
end
|
54
|
+
|
55
|
+
loop do
|
56
|
+
progressbar.increment
|
57
|
+
break if thread.status === false
|
58
|
+
|
59
|
+
if thread.status.nil?
|
60
|
+
progressbar.erase_line
|
61
|
+
say red { Manager.locale.error(self, 'execution_failed') }
|
62
|
+
|
63
|
+
exit 102
|
64
|
+
end
|
65
|
+
|
66
|
+
sleep 0.3
|
67
|
+
end
|
68
|
+
|
69
|
+
case thread[:result]
|
70
|
+
when Octokit::OneTimePasswordRequired
|
71
|
+
progressbar.erase_line
|
72
|
+
otp_interview
|
73
|
+
|
74
|
+
return deffered(&block)
|
75
|
+
when NilClass
|
76
|
+
progressbar.erase_line
|
77
|
+
say red { Manager.locale.error(self, 'empty_response') }
|
78
|
+
|
79
|
+
exit 103
|
80
|
+
when Exception
|
81
|
+
progressbar.erase_line
|
82
|
+
say red { thread[:result].message }
|
83
|
+
|
84
|
+
exit 104
|
85
|
+
else
|
86
|
+
# no-op
|
87
|
+
end
|
88
|
+
|
89
|
+
thread[:result]
|
90
|
+
end
|
91
|
+
|
92
|
+
def progressbar
|
93
|
+
@progressbar ||= Commander::UI::ProgressBar.new(100,
|
94
|
+
progress_str: ".", incomplete_str: " ", format: ":title:progress_bar",
|
95
|
+
complete_message: "", title: Manager.locale.word(self, 'configuring'))
|
96
|
+
end
|
97
|
+
|
98
|
+
def suppress(&block)
|
99
|
+
begin
|
100
|
+
block.call
|
101
|
+
rescue => error
|
102
|
+
error
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end # class Configure
|
107
|
+
end # module Commands
|
108
|
+
end # module Abak::Flow
|