gb 0.1.1

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.
@@ -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