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 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
- **Начиная с версии v0.2.1 используется авторизация OAuth2. [Как ей пользоваться?](https://github.com/Strech/abak-flow/wiki/How-start-work-with-new-abak-flow)**
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
- Github-flow же наоборот ведет основную разработку в ветке master, но при этом master является пригодным для развертывания в любой момент.
7
+ Нет, это не новая идеология ведения разработки в проекте, это всего лишь набор утилит которые помогают связать использование [git-flow](https://github.com/nvie/gitflow) и [github flow](http://scottchacon.com/2011/08/31/github-flow.html)
18
8
 
19
- После долгих раздумий было принято применить следующий набор правил, для разработки на github:
9
+ **Начиная с версии v0.2.1 используется авторизация OAuth2. [Как ей пользоваться?](https://github.com/Strech/abak-flow/wiki/How-start-work-with-new-abak-flow)**
20
10
 
21
- 1. Вся разработка любой задачи и функционала ведется только в ветках **feature**
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.0.0
17
+ $ gem install abak-flow -v '>= 1.1.0'
31
18
  $ git config --global alias.request '!request'
32
- $ git config --global abak-flow.oauth-user YOUR_GITHUB_MAIL@gmail.com
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
- $ git config --global abak-flow.http-proxy http://my-proxy.com:3129
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
- **Заметьте:** В конфиге git, значением *abak.oauth-user* должен являться тот email адрес, под которым вы заходите на github
32
+ **Важно:** Пароль никогда и нигде не будет сохранен. Он [будет использован](https://developer.github.com/v3/#basic-authentication) для создания персонального токена
33
+
34
+ **Заметьте:** При конфигурации необходимо указать email адрес под которым вы заходите на github
46
35
 
47
- **Обратите внимание:** В данном контексте под **upstream** подразумевается адрес репозитория в который будут оформляться pull request. А репозиторием **origin** будет являться ваш форк
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
- **Примечание:** Вообще-то все комманды поддерживают опцию *--help*, но вот именно *git request --help* успевает перехватиться самим git и он конечно неодумевает как ему показать хэлп по внешней комманде
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 flow feature start 'TASK-001'
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. Используйте префикс задачь из jira
83
+ **Внимание:** Не нужно называться ветку TASK. Используйте префикс задач из jira
69
84
 
70
85
  Теперь то же самое, только словами:
71
86
 
72
87
  * Переключимся в ветку develop
73
- * git-flow создаст ветку, пригодную для оформления pull request (правила именования и правила самого реквеста)
88
+ * Создадим ветку в которй будем выполнять задачу
74
89
  * Простое создание нового файла
75
- * Git процедуры добавления своих изменений в репозиторий
76
- * Затем публикация вашей ветки на вашем форке (если таковая уже есть, то просто обновление), затем оформление pull request из этой ветки в соответствующую правилам ветку на upstream (в данном случае это будет ветка develop)
90
+ * Git процедуры добавления своих изменений в индекс
91
+ * Затем публикация вашей ветки на вашем форке (если таковая уже есть, то просто обновление), затем оформление пул реквеста из этой ветки в соответствующую правилам ветку на upstream (в данном случае это будет ветка develop)
77
92
 
78
93
  Для задач, которые должны быть выполнены в виде hotfix принцип тот же:
79
94
 
80
95
  $ git checkout master
81
- $ git flow hotfix start 'TASK-001'
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.19.0"
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/visitor"
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
@@ -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
- : @manager.git.branch(branch)
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 = "#{@manager.repository.upstream.owner}:#{branch}...#{@branch}"
45
+ diff = "#{Manager.repository.upstream.owner}:#{branch}...#{@branch}"
47
46
 
48
47
  File.join [
49
- @manager.github.web_endpoint,
50
- @manager.repository.origin.to_s,
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 = @manager.repository.origin.repo
76
- @manager.git.push(origin, @branch)
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 = @manager.repository.origin.repo
81
- @manager.git.push(origin, ":#{@branch}")
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
- say ANSI.green { I18n.t("commands.checkup.success") }
9
+
10
+ say green { Manager.locale.success(self) }
18
11
  end
19
12
 
20
13
  def process(args, options)
21
- Visitor.new(@configuration, @repository,
22
- command: "checkup", call: :ready?, inspect: :errors)
23
- .on_fail(exit: 1)
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
- require "commander/blank"
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
- # TODO : Быть может стоит сделать include ANSI
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 = @git.current_branch
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 ANSI.white {
29
- I18n.t("commands.compare.updating",
30
- branch: ANSI.bold { head },
31
- upstream: ANSI.bold { "#{@repository.origin}" }) }
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 ANSI.yellow {
36
- I18n.t("commands.compare.diverging",
37
- branch: ANSI.bold { head }) }
25
+ say yellow {
26
+ Manager.locale.word(self, 'diverging', branch: bold { head })
27
+ }
38
28
  end
39
29
 
40
- say ANSI.green { head.compare_link(base) }
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