gb 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,104 @@
1
+ require 'sub_command'
2
+
3
+
4
+ module Gb
5
+
6
+ class CreateTag < SubCommand
7
+
8
+ self.summary = '新建tag'
9
+
10
+ self.description = <<-DESC
11
+ 指定分支上新建tag.
12
+ DESC
13
+
14
+ self.arguments = [
15
+ CLAide::Argument.new('branch', true, false),
16
+ CLAide::Argument.new('tag_name', true, false),
17
+ ]
18
+
19
+ def self.options
20
+ [
21
+ ["--force", "忽略tag是否存在,强制执行"],
22
+ ].concat(super)
23
+ end
24
+
25
+ def initialize(argv)
26
+ @branch = argv.shift_argument
27
+ @tag_name = argv.shift_argument
28
+ @force = argv.flag?('force')
29
+ super
30
+ end
31
+
32
+ def validate!
33
+ super
34
+ if @branch.nil?
35
+ help! 'branch is required.'
36
+ end
37
+ if @tag_name.nil?
38
+ help! 'tag_name is required.'
39
+ end
40
+ end
41
+
42
+ def run
43
+ # api: https://www.rubydoc.info/gems/gitlab/toplevel
44
+ # document: https://narkoz.github.io/gitlab/cli
45
+
46
+ Gitlab.configure do |config|
47
+ # set an API endpoint
48
+ # API endpoint URL, default: ENV['GITLAB_API_ENDPOINT']
49
+ config.endpoint = self.gb_config.gitlab.endpoint
50
+
51
+ # set a user private token
52
+ # user's private token or OAuth2 access token, default: ENV['GITLAB_API_PRIVATE_TOKEN']
53
+ config.private_token = self.gb_config.gitlab.private_token
54
+
55
+ # user agent
56
+ config.user_agent = "gb ruby gem[#{VERSION}"
57
+ end
58
+
59
+ self.gb_config.projects.each do |project|
60
+ gitlab_project = gitlab_search_project(project.name)
61
+ info "find project #{gitlab_project.name} on #{gitlab_project.web_url}."
62
+ begin
63
+ tag = Gitlab.tag(gitlab_project.id, @tag_name)
64
+ rescue Gitlab::Error::NotFound => error
65
+ tag = nil
66
+ rescue Gitlab::Error::Error => error
67
+ raise(error)
68
+ end
69
+
70
+ if tag.nil?
71
+ Gitlab.create_tag(gitlab_project.id, @tag_name, @branch)
72
+ info "create tag '#{@tag_name}' success"
73
+ else
74
+ if @force
75
+ info "tag '#{@tag_name}' exist, skip."
76
+ else
77
+ help! "tag '#{@tag_name}' exist."
78
+ end
79
+ end
80
+
81
+ puts
82
+ end
83
+ end
84
+
85
+ def gitlab_search_project(project_name)
86
+ projects = Gitlab.project_search(project_name)
87
+ if projects.size > 1
88
+ info "find #{projects.size} project named #{project_name}. you means which one?"
89
+ projects.each do |project|
90
+ print project.name + ' '
91
+ end
92
+ print "\n"
93
+ raise Error.new("find #{projects.size} project named #{project_name}")
94
+
95
+ elsif projects.size == 1
96
+ project = projects[0];
97
+ else
98
+ raise Error.new("can't find project named '#{project_name}'.")
99
+ end
100
+ project
101
+ end
102
+
103
+ end
104
+ end
@@ -0,0 +1,98 @@
1
+ require 'sub_command'
2
+
3
+
4
+ module Gb
5
+
6
+ class DeleteTag < SubCommand
7
+
8
+ self.summary = '删除tag'
9
+
10
+ self.description = <<-DESC
11
+ 删除指定tag.
12
+ DESC
13
+
14
+ self.arguments = [
15
+ CLAide::Argument.new('tag_name', true, false),
16
+ ]
17
+
18
+ def self.options
19
+ [
20
+ ["--force", "忽略tag是否存在,强制执行"],
21
+ ].concat(super)
22
+ end
23
+
24
+ def initialize(argv)
25
+ @tag_name = argv.shift_argument
26
+ @force = argv.flag?('force')
27
+ super
28
+ end
29
+
30
+ def validate!
31
+ super
32
+ if @tag_name.nil?
33
+ help! 'tag_name is required.'
34
+ end
35
+ end
36
+
37
+ def run
38
+ # api: https://www.rubydoc.info/gems/gitlab/toplevel
39
+ # document: https://narkoz.github.io/gitlab/cli
40
+
41
+ Gitlab.configure do |config|
42
+ # set an API endpoint
43
+ # API endpoint URL, default: ENV['GITLAB_API_ENDPOINT']
44
+ config.endpoint = self.gb_config.gitlab.endpoint
45
+
46
+ # set a user private token
47
+ # user's private token or OAuth2 access token, default: ENV['GITLAB_API_PRIVATE_TOKEN']
48
+ config.private_token = self.gb_config.gitlab.private_token
49
+
50
+ # user agent
51
+ config.user_agent = "gb ruby gem[#{VERSION}"
52
+ end
53
+
54
+ info "ready delete tag '#{@tag_name}'.\n"
55
+
56
+ self.gb_config.projects.each do |project|
57
+ gitlab_project = gitlab_search_project(project.name)
58
+ info "find project #{gitlab_project.name} on #{gitlab_project.web_url}."
59
+
60
+ begin
61
+ tag = Gitlab.delete_tag(gitlab_project.id, @tag_name)
62
+ rescue Gitlab::Error::NotFound => error
63
+ tag = nil
64
+ if @force
65
+ raise(error)
66
+ else
67
+ info "tag '#{@tag_name}' not found, skip."
68
+ end
69
+ rescue Gitlab::Error::Error => error
70
+ raise(error)
71
+ end
72
+ if tag
73
+ info "delete tag '#{@tag_name}' success.\n"
74
+ end
75
+ puts
76
+ end
77
+ end
78
+
79
+ def gitlab_search_project(project_name)
80
+ projects = Gitlab.project_search(project_name)
81
+ if projects.size > 1
82
+ info "find #{projects.size} project named #{project_name}. you means which one?"
83
+ projects.each do |project|
84
+ print project.name + ' '
85
+ end
86
+ print "\n"
87
+ raise Error.new("find #{projects.size} project named #{project_name}")
88
+
89
+ elsif projects.size == 1
90
+ project = projects[0];
91
+ else
92
+ raise Error.new("can't find project named '#{project_name}'.")
93
+ end
94
+ project
95
+ end
96
+
97
+ end
98
+ end
@@ -0,0 +1,53 @@
1
+ require 'sub_command'
2
+
3
+
4
+ module Gb
5
+
6
+ class Forall < SubCommand
7
+
8
+ self.summary = '遍历所有工程执行命令'
9
+ self.description = <<-DESC
10
+ 遍历所有工程执行命令.
11
+ gb forall -c="git reset --hard"
12
+ DESC
13
+
14
+ def self.options
15
+ [
16
+ ["-c", "执行命令"],
17
+ ].concat(super)
18
+ end
19
+
20
+ def initialize(argv)
21
+ @command = argv.option('c')
22
+ super
23
+ end
24
+
25
+ def validate!
26
+ super
27
+ if @command.nil?
28
+ help! 'command is required.'
29
+ end
30
+ end
31
+
32
+ def run_in_workspace
33
+
34
+ self.gb_config.projects.each do |project|
35
+ project_path = File.expand_path(project.name, './')
36
+
37
+ if File.exist?(project_path)
38
+ info "For project '#{project.name}'..."
39
+ g = Git.open(project_path)
40
+ Dir.chdir(project_path) do
41
+ result = `#{@command}`
42
+ puts result
43
+ end
44
+ puts
45
+ else
46
+ error "please run 'gb init first."
47
+ break
48
+ end
49
+ end
50
+ end
51
+
52
+ end
53
+ end
@@ -0,0 +1,36 @@
1
+ require 'sub_command'
2
+
3
+ module Gb
4
+
5
+ class Init < SubCommand
6
+
7
+ self.summary = '根据yml配置,更新代码'
8
+
9
+ self.description = <<-DESC
10
+ 根据yml配置,更新代码.
11
+ DESC
12
+
13
+ def run
14
+ mutex = Mutex.new
15
+ threads = []
16
+ self.gb_config.projects.each do |project|
17
+ t = Thread.new do
18
+ project_path = File.expand_path(project.name, './')
19
+ if File.exist?(project_path)
20
+ mutex.synchronize do
21
+ info project.name + ' exists, skip.'
22
+ end
23
+ else
24
+ Git.clone_without_env(project.git, project.name, :path => './')
25
+ end
26
+ end
27
+ threads << t
28
+ end
29
+ threads.each do |t|
30
+ t.join
31
+ end
32
+ puts "#{self.gb_config.projects.size} projects init success.".green
33
+ end
34
+ end
35
+
36
+ end
@@ -0,0 +1,249 @@
1
+ require 'sub_command'
2
+ require 'ext/gitlab_ext'
3
+
4
+ module Gb
5
+ class Merge < SubCommand
6
+
7
+ self.summary = '创建gitlab merge request,注意跟review的区别是不会同步本地分支代码.'
8
+
9
+ self.description = <<-DESC
10
+ 创建gitlab merge request,注意跟review的区别是不会同步本地分支代码.
11
+
12
+ gb merge from_branch to_branch
13
+ DESC
14
+
15
+ self.arguments = [
16
+ CLAide::Argument.new('from_branch', true, false),
17
+ CLAide::Argument.new('to_branch', true, false),
18
+ ]
19
+
20
+ def self.options
21
+ [
22
+ ["--assignee=[user name]", "指定review用户名称"],
23
+ ["--title", "merge request标题"],
24
+ ["--show-diff", "review前是否显示变更"],
25
+ ].concat(super)
26
+ end
27
+
28
+ def initialize(argv)
29
+ @from_branch = argv.shift_argument
30
+ @to_branch = argv.shift_argument
31
+ @assignee = argv.option('assignee')
32
+ @title = argv.option('title')
33
+ @show_diff = argv.flag?('show-diff')
34
+ super
35
+ end
36
+
37
+ def validate!
38
+ super
39
+ if @from_branch.nil?
40
+ help! 'from_branch is required.'
41
+ end
42
+ if @to_branch.nil?
43
+ help! 'remote_branch is required.'
44
+ end
45
+ end
46
+
47
+ def run_in_workspace
48
+ remote = "origin"
49
+
50
+ # api: https://www.rubydoc.info/gems/gitlab/toplevel
51
+ # document: https://narkoz.github.io/gitlab/cli
52
+
53
+ Gitlab.configure do |config|
54
+ # set an API endpoint
55
+ # API endpoint URL, default: ENV['GITLAB_API_ENDPOINT']
56
+ config.endpoint = self.gb_config.gitlab.endpoint
57
+
58
+ # set a user private token
59
+ # user's private token or OAuth2 access token, default: ENV['GITLAB_API_PRIVATE_TOKEN']
60
+ config.private_token = self.gb_config.gitlab.private_token
61
+
62
+ # user agent
63
+ config.user_agent = "gb ruby gem[#{VERSION}"
64
+ end
65
+
66
+ user = nil
67
+ if !@assignee.nil?
68
+ user = gitlab_search_user(@assignee)
69
+ end
70
+
71
+ self.gb_config.projects.each_with_index do |project, index|
72
+
73
+ gitlab_project = gitlab_search_project(project.name)
74
+ info "Find project #{gitlab_project.name} on #{gitlab_project.web_url}."
75
+
76
+ begin
77
+ Gitlab.branch(gitlab_project.id, @from_branch)
78
+ rescue Gitlab::Error::NotFound => error
79
+ raise Error.new("Branch '#{@from_branch}' not exist in remote '#{remote}'.")
80
+ rescue Gitlab::Error::Error => error
81
+ raise(error)
82
+ end
83
+
84
+ begin
85
+ Gitlab.branch(gitlab_project.id, @to_branch)
86
+ rescue Gitlab::Error::NotFound => error
87
+ raise Error.new("Branch '#{@to_branch}' not exist in remote '#{remote}'.")
88
+ rescue Gitlab::Error::Error => error
89
+ raise(error)
90
+ end
91
+
92
+ compare_response = Gitlab.compare(gitlab_project.id, @to_branch, @from_branch);
93
+ if compare_response.commits.size >= 1
94
+ if @show_diff
95
+ puts "\ncommits"
96
+ compare_response.commits.each_with_index do |commit, index|
97
+ unless index == 0
98
+ puts ""
99
+ end
100
+ puts " #{index} id:" + commit["id"]
101
+ puts " author:" + commit["author_name"]
102
+ puts " create at: " + commit["created_at"]
103
+ puts " title: " + commit["title"]
104
+ end
105
+ puts ""
106
+ end
107
+ else
108
+ info "Can't find new commit on #{@from_branch} to #{@to_branch} in project #{project.name}."
109
+ puts
110
+ next
111
+ end
112
+
113
+ if compare_response.diffs.size >= 1
114
+ if @show_diff
115
+ puts "Diffs"
116
+ compare_response.diffs.each do |diff|
117
+ if diff["new_file"]
118
+ puts " created " + diff["new_path"]
119
+ elsif diff["renamed_file"]
120
+ puts " renamed " + diff["old_path"] + "=>" + diff["new_path"]
121
+ elsif diff["deleted_file"]
122
+ puts " deleted" + diff["old_path"]
123
+ else
124
+ puts " edited " + diff["new_path"]
125
+ end
126
+
127
+ diff = diff["diff"];
128
+ lines = diff.split("\n")
129
+ lines.each do |line|
130
+ puts " " + line
131
+ end
132
+
133
+ end
134
+ end
135
+ else
136
+ info "Can't find diff between #{@from_branch} and #{@to_branch} in project #{project.name}."
137
+ puts
138
+ next
139
+ end
140
+
141
+ if user.nil?
142
+ users = gitlab_get_team_members(gitlab_project.id)
143
+ begin
144
+ info "\nSelect user name or index for review."
145
+ input_user = STDIN.gets.chomp
146
+ if input_user =~ /[[:digit:]]/
147
+ user = users[input_user.to_i - 1]
148
+ else
149
+ user = gitlab_search_user(input_user)
150
+ end
151
+ if user.nil?
152
+ error "Can not found user '#{input_user}'."
153
+ else
154
+ info "Assign to #{user.username}(#{user.name})"
155
+ end
156
+ end until !user.nil?
157
+ end
158
+
159
+ if @title.nil? || @title.empty?
160
+ begin
161
+ info "\nInput merge request title for project '#{project.name}'"
162
+ @title = STDIN.gets.chomp
163
+ end until @title.length > 0
164
+ end
165
+
166
+ # 总共 0 (差异 0),复用 0 (差异 0)
167
+ # remote:
168
+ # remote: To create a merge request for dev-v3.9.0-luobin, visit:
169
+ # remote: http://git.tianxiao100.com/tianxiao-ios/tianxiao/tianxiao-base-iphone-sdk/merge_requests/new?merge_request%5Bfrom_branch%5D=dev-v3.9.0-luobin
170
+ # remote:
171
+ # To http://git.tianxiao100.com/tianxiao-ios/tianxiao/tianxiao-base-iphone-sdk.git
172
+ # * [new branch] dev-v3.9.0-luobin -> dev-v3.9.0-luobin
173
+
174
+ begin
175
+ merge_request = Gitlab.create_merge_request(gitlab_project.id, @title,
176
+ { source_branch: @from_branch, target_branch: @to_branch, assignee_id:user ? user.id : "" })
177
+ info "Create merge request for #{project.name} success. see detail url:#{merge_request.web_url}"
178
+ if !Gem.win_platform?
179
+ `open -a "/Applications/Google Chrome.app" '#{merge_request.web_url}/diffs'`
180
+ exitstatus = $?.exitstatus
181
+ if exitstatus != 0
182
+ raise Error.new("open chrome failed.")
183
+ else
184
+ # info "Please review diff, then input any to continue."
185
+ # STDIN.gets.chomp
186
+ end
187
+ end
188
+ rescue Gitlab::Error::Conflict => error
189
+ # merge exists
190
+ info "Merge request from '#{@from_branch}' to '#{@to_branch}' exist."
191
+ rescue Gitlab::Error::Error => error
192
+ raise(error)
193
+ end
194
+ puts
195
+
196
+ end
197
+ end
198
+
199
+ def gitlab_search_user(assignee)
200
+ users = Gitlab.user_search(assignee)
201
+ if users.size > 1
202
+ info "Find more than one user. you means which one?"
203
+ users.each do |user|
204
+ print user.name + ' '
205
+ end
206
+ info ""
207
+ raise Error.new("Find #{users.size} user named #{project.name}")
208
+ elsif users.size == 1
209
+ user = users[0]
210
+ else
211
+ raise Error.new("Can't find user #{assignee}.")
212
+ end
213
+ user
214
+ end
215
+
216
+ def gitlab_search_project(project_name)
217
+ projects = Gitlab.project_search(project_name)
218
+ if projects.size > 1
219
+ info "Find #{projects.size} project named #{project_name}. you means which one?"
220
+ projects.each do |project|
221
+ print project.name + ' '
222
+ end
223
+ print "\n"
224
+ raise Error.new("Find #{projects.size} project named #{project_name}")
225
+
226
+ elsif projects.size == 1
227
+ project = projects[0];
228
+ else
229
+ raise Error.new("Can't find project named '#{project_name}'.")
230
+ end
231
+ project
232
+ end
233
+
234
+ def gitlab_get_team_members(project_id)
235
+ users = Gitlab.project_usesrs(project_id).delete_if { |user|
236
+ user.username == 'root'
237
+ }
238
+ if users.size > 0
239
+ info "Find user to assign."
240
+ users.each_with_index do |user, index|
241
+ puts "#{index + 1}、#{user.username}(#{user.name})".green
242
+ end
243
+ else
244
+ raise Error.new("Can't find members in project '#{project_id}''.")
245
+ end
246
+ users
247
+ end
248
+ end
249
+ end