gtlab 0.1.0

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