gtlab 0.1.0

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