gitsflow 0.6.3 → 0.8.2.alfa
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.env.yml +1 -0
- data/Gemfile.lock +66 -3
- data/README.md +5 -28
- data/bin/sflow +2 -2
- data/gitsflow.gemspec +62 -34
- data/lib/Git/git.rb +42 -42
- data/lib/GitLab/gitlab.rb +79 -46
- data/lib/GitLab/issue.rb +84 -52
- data/lib/GitLab/merge_request.rb +76 -57
- data/lib/GitLab/user.rb +3 -3
- data/lib/Utils/changelog.rb +10 -0
- data/lib/Utils/putdotenv.rb +3 -0
- data/lib/command.rb +19 -0
- data/lib/config.rb +30 -12
- data/lib/menu.rb +253 -0
- data/lib/sflow/sflow.rb +666 -0
- data/lib/sflow/version.rb +3 -0
- data/lib/tty_integration.rb +50 -0
- metadata +298 -11
- data/lib/sflow.rb +0 -651
data/lib/menu.rb
ADDED
@@ -0,0 +1,253 @@
|
|
1
|
+
require 'sflow/sflow'
|
2
|
+
require 'Git/git'
|
3
|
+
require 'GitLab/gitlab'
|
4
|
+
require 'tty_integration'
|
5
|
+
class Menu
|
6
|
+
include TtyIntegration
|
7
|
+
|
8
|
+
def principal
|
9
|
+
prompt.say("\n")
|
10
|
+
|
11
|
+
result = prompt.select("\O que você gostaria de fazer?", symbols: { marker: '>' }, per_page: 10) do |menu|
|
12
|
+
menu.choice 'INICIAR uma nova BRANCH', :start_branch
|
13
|
+
menu.choice 'FINALIZAR uma BRANCH', :finish_branch
|
14
|
+
menu.choice 'ENVIAR para HOMOLOGAÇÃO', :staging_branch
|
15
|
+
menu.choice 'Fazer CODE REVIEW ', :codereview
|
16
|
+
menu.choice 'INICIAR uma RELEASE', :release_start
|
17
|
+
menu.choice 'FINALIZAR uma RELEASE', :release_finish
|
18
|
+
# menu.choice "MOVE a Issue", :staging_branch, disabled: '(Coming Soon)'
|
19
|
+
# menu.choice "List my Issues", :staging_branch, disabled: '(Coming Soon)'
|
20
|
+
menu.choice 'Configurar', :setup_variables
|
21
|
+
# menu.choice "Help", 5
|
22
|
+
menu.choice 'SAIR', :exit
|
23
|
+
end
|
24
|
+
send(result)
|
25
|
+
end
|
26
|
+
|
27
|
+
def setup_variables
|
28
|
+
system('clear')
|
29
|
+
project_name = Git.execute do
|
30
|
+
"git remote -v | head -n1 | awk '{print $2}' | sed -e 's,.*:\(.*/\)\?,,' -e 's/\.git$//'"
|
31
|
+
end
|
32
|
+
file = "#{Dir.home}/.config/gitsflow/#{project_name.gsub("\n", '')}/config.yml"
|
33
|
+
config = TTY::Config.new
|
34
|
+
config.filename = file
|
35
|
+
prompt.say("\n")
|
36
|
+
box = TTY::Box.frame align: :left, width: TTY::Screen.width, height: 15,
|
37
|
+
title: { top_left: pastel.green('Olá, seja bem-vindo!') } do
|
38
|
+
pastel.green("\nVamos configurar o GitSFlow agora.\n\n") +
|
39
|
+
pastel.white("Essa informação será salva dentro da pasta home do seu usuário. Você não precisará mais do .env
|
40
|
+
\nSe você desejar apenas ver as configurações, tecle enter até o final ou acesse o conteudo do arquivo: #{file}\nEssa informação será salva dentro da pasta home do seu usuário. Você não precisará mais do .env")
|
41
|
+
end
|
42
|
+
print box
|
43
|
+
prompt.say(pastel.cyan('Agora, entre com as informações de configuração do projeto.'))
|
44
|
+
begin
|
45
|
+
result_env = config.read(file).transform_keys(&:to_sym)
|
46
|
+
result = prompt.collect do
|
47
|
+
key(:GITLAB_PROJECT_ID).ask('GITLAB_PROJECT_ID:', required: true, default: result_env[:GITLAB_PROJECT_ID])
|
48
|
+
key(:GITLAB_TOKEN).mask('GITLAB_TOKEN:', required: true, echo: true, default: result_env[:GITLAB_TOKEN])
|
49
|
+
key(:GITLAB_URL_API).ask('GITLAB_URL_API:', required: true, default: result_env[:GITLAB_URL_API] || 'https://gitlab.com/api/v4')
|
50
|
+
key(:GITLAB_EMAIL).ask('GITLAB_EMAIL:', required: true, default: result_env[:GITLAB_EMAIL]) do |q|
|
51
|
+
q.validate(/[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+/, 'Invalid email address')
|
52
|
+
end
|
53
|
+
key(:GITLAB_LISTS).ask('GITLAB_LISTS:', required: true,
|
54
|
+
default: result_env[:GITLAB_LISTS] || 'To Do,Doing,Next Release,Staging')
|
55
|
+
key(:GITLAB_NEXT_RELEASE_LIST).ask('GITLAB_NEXT_RELEASE_LIST:', required: true,
|
56
|
+
default: result_env[:GITLAB_NEXT_RELEASE_LIST] || 'Next Release')
|
57
|
+
key(:GIT_BRANCH_MASTER).ask('GIT_BRANCH_MASTER:', required: true,
|
58
|
+
default: result_env[:GIT_BRANCH_MASTER] || 'master')
|
59
|
+
key(:GIT_BRANCH_DEVELOP).ask('GIT_BRANCH_DEVELOP:', required: true,
|
60
|
+
default: result_env[:GIT_BRANCH_DEVELOP] || 'developer')
|
61
|
+
key(:GIT_BRANCHES_STAGING).ask('GIT_BRANCHES_STAGING:', required: true,
|
62
|
+
default: result_env[:GIT_BRANCHES_STAGING] || 'staging')
|
63
|
+
key(:SFLOW_TEMPLATE_RELEASE).ask('SFLOW_TEMPLATE_RELEASE:', required: true,
|
64
|
+
default: result_env[:SFLOW_TEMPLATE_RELEASE] || 'Version {version} - {date}')
|
65
|
+
key(:SFLOW_TEMPLATE_RELEASE_DATE_FORMAT).ask('SFLOW_TEMPLATE_RELEASE_DATE_FORMAT:', required: true,
|
66
|
+
default: result_env['SFLOW_TEMPLATE_RELEASE_DATE_FORMAT'] || 'Y/m/d')
|
67
|
+
end
|
68
|
+
rescue TTY::Config::ReadError => e
|
69
|
+
prompt.say(pastel.cyan("\n\nPor favor configure as variáveis .env"))
|
70
|
+
result = prompt.collect do
|
71
|
+
key(:GITLAB_PROJECT_ID).ask('GITLAB_PROJECT_ID:', required: true, default: ENV['GITLAB_PROJECT_ID'])
|
72
|
+
key(:GITLAB_TOKEN).mask('GITLAB_TOKEN:', required: true, echo: true, default: ENV['GITLAB_TOKEN'])
|
73
|
+
key(:GITLAB_URL_API).ask('GITLAB_URL_API:', required: true, default: ENV['GITLAB_URL_API'] || 'https://gitlab.com/api/v4')
|
74
|
+
key(:GITLAB_EMAIL).ask('GITLAB_EMAIL:', required: true, default: ENV['GITLAB_EMAIL']) do |q|
|
75
|
+
q.validate(/[^@ \t\r\n]+@[^@ \t\r\n]+\.[^@ \t\r\n]+/, 'Invalid email address')
|
76
|
+
end
|
77
|
+
key(:GITLAB_LISTS).ask('GITLAB_LISTS:', required: true,
|
78
|
+
default: ENV['GITLAB_LISTS'] || 'To Do,Doing,Staging,Next Release')
|
79
|
+
key(:GITLAB_NEXT_RELEASE_LIST).ask('GITLAB_NEXT_RELEASE_LIST:', required: true,
|
80
|
+
default: ENV['GITLAB_NEXT_RELEASE_LIST'] || 'Next Release')
|
81
|
+
key(:GIT_BRANCH_MASTER).ask('GIT_BRANCH_MASTER:', required: true, default: ENV['GIT_BRANCH_MASTER'] || 'master')
|
82
|
+
key(:GIT_BRANCH_DEVELOP).ask('GIT_BRANCH_DEVELOP:', required: true,
|
83
|
+
default: ENV['GIT_BRANCH_DEVELOP'] || 'developer')
|
84
|
+
key(:GIT_BRANCHES_STAGING).ask('GIT_BRANCHES_STAGING:', required: true,
|
85
|
+
default: ENV['GIT_BRANCHES_STAGING'] || 'staging')
|
86
|
+
key(:SFLOW_TEMPLATE_RELEASE).ask('SFLOW_TEMPLATE_RELEASE:', required: true,
|
87
|
+
default: ENV['SFLOW_TEMPLATE_RELEASE'] || 'Version {version} - {date}')
|
88
|
+
key(:SFLOW_TEMPLATE_RELEASE_DATE_FORMAT).ask('SFLOW_TEMPLATE_RELEASE_DATE_FORMAT:', required: true,
|
89
|
+
default: ENV['SFLOW_TEMPLATE_RELEASE_DATE_FORMAT'] || 'Y/m/d')
|
90
|
+
end
|
91
|
+
config.set(:GITLAB_PROJECT_ID, value: result[:GITLAB_PROJECT_ID])
|
92
|
+
config.set(:GITLAB_TOKEN, value: result[:GITLAB_TOKEN])
|
93
|
+
config.set(:GITLAB_URL_API, value: result[:GITLAB_URL_API])
|
94
|
+
config.set(:GITLAB_EMAIL, value: result[:GITLAB_EMAIL])
|
95
|
+
config.set(:GITLAB_LISTS, value: result[:GITLAB_LISTS])
|
96
|
+
config.set(:GITLAB_NEXT_RELEASE_LIST, value: result[:GITLAB_NEXT_RELEASE_LIST])
|
97
|
+
config.set(:GIT_BRANCH_MASTER, value: result[:GIT_BRANCH_MASTER])
|
98
|
+
config.set(:GIT_BRANCH_DEVELOP, value: result[:GIT_BRANCH_DEVELOP])
|
99
|
+
config.set(:GIT_BRANCHES_STAGING, value: result[:GIT_BRANCHES_STAGING])
|
100
|
+
config.set(:SFLOW_TEMPLATE_RELEASE, value: result[:SFLOW_TEMPLATE_RELEASE])
|
101
|
+
config.set(:SFLOW_TEMPLATE_RELEASE_DATE_FORMAT, value: result[:SFLOW_TEMPLATE_RELEASE_DATE_FORMAT])
|
102
|
+
config.write(file, force: true, create: true)
|
103
|
+
end
|
104
|
+
|
105
|
+
prompt.say(pastel.cyan("\n"))
|
106
|
+
prompt.say(pastel.cyan(file.gsub(Dir.home, '~')))
|
107
|
+
prompt.say(pastel.cyan("\n\n"))
|
108
|
+
|
109
|
+
$GITLAB_PROJECT_ID = result[:GITLAB_PROJECT_ID]
|
110
|
+
$GITLAB_TOKEN = result[:GITLAB_TOKEN]
|
111
|
+
$GITLAB_URL_API = result[:GITLAB_URL_API]
|
112
|
+
$GITLAB_EMAIL = result[:GITLAB_EMAIL]
|
113
|
+
$GITLAB_LISTS = result[:GITLAB_LISTS].split(',')
|
114
|
+
$GITLAB_NEXT_RELEASE_LIST = result[:GITLAB_NEXT_RELEASE_LIST]
|
115
|
+
$GIT_BRANCH_MASTER = result[:GIT_BRANCH_MASTER]
|
116
|
+
$GIT_BRANCH_DEVELOP = result[:GIT_BRANCH_DEVELOP]
|
117
|
+
$GIT_BRANCHES_STAGING = result[:GIT_BRANCHES_STAGING].split(',')
|
118
|
+
$SFLOW_TEMPLATE_RELEASE = result[:SFLOW_TEMPLATE_RELEASE]
|
119
|
+
$SFLOW_TEMPLATE_RELEASE_DATE_FORMAT = result[:SFLOW_TEMPLATE_RELEASE_DATE_FORMAT]
|
120
|
+
|
121
|
+
GitLab.create_labels
|
122
|
+
GitLab.create_board_lists
|
123
|
+
|
124
|
+
success('GitSFlow coonfigurado com sucesso!')
|
125
|
+
|
126
|
+
principal if prompt.yes?('Vocẽ gostaria de voltar ao menu principal?')
|
127
|
+
prompt.say(pastel.cyan('Até logo!'))
|
128
|
+
end
|
129
|
+
|
130
|
+
private
|
131
|
+
|
132
|
+
def codereview
|
133
|
+
result = choice_branch('codereview')
|
134
|
+
SFlow::SFlow.send(:codereview, result[:branch_name])
|
135
|
+
end
|
136
|
+
|
137
|
+
def release_start
|
138
|
+
SFlow::SFlow.send(:release_start)
|
139
|
+
end
|
140
|
+
|
141
|
+
def release_finish
|
142
|
+
result = choice_branch_release
|
143
|
+
|
144
|
+
SFlow::SFlow.send(:release_finish, result[:branch_name])
|
145
|
+
end
|
146
|
+
|
147
|
+
def exit
|
148
|
+
0
|
149
|
+
end
|
150
|
+
|
151
|
+
def staging_branch
|
152
|
+
result = choice_branch('staging')
|
153
|
+
SFlow::SFlow.send(result[:action], result[:branch_name])
|
154
|
+
end
|
155
|
+
|
156
|
+
def finish_branch
|
157
|
+
result = choice_branch('finish')
|
158
|
+
SFlow::SFlow.send(result[:action], result[:branch_name])
|
159
|
+
end
|
160
|
+
|
161
|
+
def start_branch
|
162
|
+
action = prompt.select('Selecione o tipo de Branch:', symbols: { marker: '>' }) do |menu|
|
163
|
+
menu.choice 'Feature', :feature_start
|
164
|
+
menu.choice 'Bugfix', :bugfix_start
|
165
|
+
menu.choice 'Hotfix', :hotfix_start
|
166
|
+
end
|
167
|
+
parent_branch_name = nil
|
168
|
+
if prompt.yes? 'Essa branch possui alguma branch pai ou epic?'
|
169
|
+
|
170
|
+
# branchs_list = Git.execute { "git branch -r --format='%(refname)' --sort=-committerdate" }
|
171
|
+
branchs_list = Git.execute { "git ls-remote --heads --refs | awk '{print $2}'" }
|
172
|
+
branchs_list = branchs_list.gsub('refs/heads/',
|
173
|
+
'').split("\n") - ($GIT_BRANCHES_STAGING + [$GIT_BRANCH_MASTER,
|
174
|
+
$GIT_BRANCH_DEVELOP])
|
175
|
+
branchs_list.unshift('Não encontrei na lista, quero criar uma nova branch')
|
176
|
+
parent_branch_name = prompt.select('Selecione a Branch PAI:', branchs_list, symbols: { marker: '>' },
|
177
|
+
filter: true)
|
178
|
+
if parent_branch_name == 'Não encontrei na lista, quero criar uma nova branch'
|
179
|
+
|
180
|
+
prompt.say("\n")
|
181
|
+
prompt.say(pastel.cyan("Ok, vamos seguir com o cadastro da branch Pai\n"))
|
182
|
+
result_parent_branch = prompt.collect do
|
183
|
+
key(:parent_external_id_ref).ask(
|
184
|
+
'Digite o código de identificação da Branch Pai, EX: [JiraIssueKey, TicketOtrsID]:', required: true
|
185
|
+
)
|
186
|
+
key(:parent_branch_description).ask('Descrição da branch Pai:', required: false)
|
187
|
+
end
|
188
|
+
parent_issue = SFlow::SFlow.send(action, result_parent_branch[:parent_external_id_ref].strip,
|
189
|
+
result_parent_branch[:parent_branch_description].strip)
|
190
|
+
parent_branch_name = parent_issue.description.strip.gsub('* ~default_branch ', '')
|
191
|
+
end
|
192
|
+
end
|
193
|
+
prompt.say("\n")
|
194
|
+
prompt.say(pastel.cyan("Agora, entre com as informações da branch de trabalho \n"))
|
195
|
+
|
196
|
+
result = prompt.collect do
|
197
|
+
key(:external_id_ref).ask('Digite o código de identificação da Branch, EX: [JiraIssueKey, TicketOtrsID]:',
|
198
|
+
required: true)
|
199
|
+
key(:branch_description).ask('Descrição da branch:', required: true)
|
200
|
+
end
|
201
|
+
|
202
|
+
SFlow::SFlow.send(action, result[:external_id_ref].strip, result[:branch_description].strip, parent_branch_name)
|
203
|
+
end
|
204
|
+
|
205
|
+
def choice_branch_release
|
206
|
+
branchs_list = Git.execute { "git ls-remote --heads --refs | awk '{print $2}' | grep release" }
|
207
|
+
branchs_list = branchs_list.gsub('refs/heads/',
|
208
|
+
'').split("\n") - ($GIT_BRANCHES_STAGING + [$GIT_BRANCH_MASTER,
|
209
|
+
$GIT_BRANCH_DEVELOP])
|
210
|
+
branch_name = prompt.select('Selecione a Branch:', branchs_list, symbols: { marker: '>' }, filter: true)
|
211
|
+
{
|
212
|
+
branch_name: branch_name.delete("\n")
|
213
|
+
}
|
214
|
+
end
|
215
|
+
|
216
|
+
def choice_branch(type)
|
217
|
+
action = ''
|
218
|
+
current_branch = Git.execute { 'git branch --show-current' }
|
219
|
+
branch_origin = prompt.select('Confirme a branch:', symbols: { marker: '>' }) do |menu|
|
220
|
+
menu.choice "#{current_branch}(Atual)", :current
|
221
|
+
menu.choice 'Outra', :other_branch
|
222
|
+
end
|
223
|
+
|
224
|
+
case branch_origin
|
225
|
+
when :current
|
226
|
+
if current_branch.match(%r{-feature/})
|
227
|
+
action = "feature_#{type}"
|
228
|
+
elsif current_branch.match(%r{-bugfix/})
|
229
|
+
action = "bugfix_#{type}"
|
230
|
+
elsif current_branch.match(%r{-hotfix/})
|
231
|
+
action = "hotfix_#{type}"
|
232
|
+
end
|
233
|
+
branch_name = current_branch.delete("\n")
|
234
|
+
when :other_branch
|
235
|
+
branchs_list = Git.execute { "git ls-remote --heads --refs | awk '{print $2}'" }
|
236
|
+
branchs_list = branchs_list.gsub('refs/heads/',
|
237
|
+
'').split("\n") - ($GIT_BRANCHES_STAGING + [$GIT_BRANCH_MASTER,
|
238
|
+
$GIT_BRANCH_DEVELOP])
|
239
|
+
branch_name = prompt.select('Selecione a Branch:', branchs_list, symbols: { marker: '>' }, filter: true)
|
240
|
+
if branch_name.match(%r{-feature/})
|
241
|
+
action = "feature_#{type}"
|
242
|
+
elsif branch_name.match(%r{-bugfix/})
|
243
|
+
action = "bugfix_#{type}"
|
244
|
+
elsif branch_name.match(%r{-hotfix/})
|
245
|
+
action = "hotfix_#{type}"
|
246
|
+
end
|
247
|
+
end
|
248
|
+
{
|
249
|
+
action: action,
|
250
|
+
branch_name: branch_name.delete("\n")
|
251
|
+
}
|
252
|
+
end
|
253
|
+
end
|