abak-flow 1.0.10 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](https://codeclimate.com/github/Strech/abak-flow)
|
5
|
+
[](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
|