Update Tizen 2.0 SDK source code
[sdk/tools/sdk-build.git] / src / build_server / ProjectManager.rb
1 =begin
2  
3  ProjectManager.rb
4
5 Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6
7 Contact:
8 Taejun Ha <taejun.ha@samsung.com>
9 Jiil Hyoun <jiil.hyoun@samsung.com>
10 Donghyuk Yang <donghyuk.yang@samsung.com>
11 DongHee Yang <donghee.yang@samsung.com>
12
13 Licensed under the Apache License, Version 2.0 (the "License");
14 you may not use this file except in compliance with the License.
15 You may obtain a copy of the License at
16
17 http://www.apache.org/licenses/LICENSE-2.0
18
19 Unless required by applicable law or agreed to in writing, software
20 distributed under the License is distributed on an "AS IS" BASIS,
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 See the License for the specific language governing permissions and
23 limitations under the License.
24
25 Contributors:
26 - S-Core Co., Ltd
27 =end
28
29 require 'fileutils'
30 $LOAD_PATH.unshift File.dirname(__FILE__)
31 require "GitBuildProject.rb"
32 require "BinaryUploadProject.rb"
33 require "MultiBuildJob.rb"
34 require "PackageManifest.rb"
35 require "package.rb"
36
37 class ProjectManager
38         attr_accessor :projects
39
40         # initialize
41         def initialize( server )
42                 @server = server
43                 @projects = []
44                 @project_root = "#{@server.path}/projects"
45         end
46
47
48         # load existing project from server configuration
49         def load()
50                 # check project root
51                 if not File.exist? @project_root then
52                         FileUtils.mkdir_p @project_root
53                 end
54
55                 # scan all projects 
56                 Dir.new(@project_root).entries.each do |name|
57                         # skip . or ..
58                         if name.eql? "." or name.eql? ".." then next end
59                                 
60                         # create project
61                         @server.log.info "Loading project : #{name}"
62                         prj = load_project( name )
63                         if not prj.nil? then 
64                                 @projects.push prj
65                         end
66                 end
67
68         end
69
70
71         # get_project of the name
72         def get_project ( name )
73                 @projects.each do |prj|
74                         if prj.name.eql? name then return prj end
75                 end
76         
77                 return nil
78         end
79
80
81         def add_git_project(name , repos, branch, passwd, os_list)
82                 prj = get_project( name)
83                 if not prj.nil? then return false end
84                 
85                 new_prj = GitBuildProject.new(name, repos, branch, @server, os_list)
86                 if not passwd.nil? and not passwd.empty? then
87                         new_prj.passwd = passwd
88                 end
89                 @projects.push new_prj
90
91                 # check project directory
92                 if not File.exist? "#{@project_root}/#{name}" then
93                         FileUtils.mkdir_p "#{@project_root}/#{name}"
94                 end
95
96                 # write configuration
97                 write_configuration(name, repos, branch, passwd, os_list)
98
99                 return true
100         end
101
102
103         def add_binary_project(name, pkg_name, passwd, os_list)
104                 prj = get_project( name)
105                 if not prj.nil? then return false end
106                 
107                 new_prj = BinaryUploadProject.new(name, pkg_name, @server, os_list)
108                 if not passwd.nil? and not passwd.empty? then
109                         new_prj.passwd = passwd
110                 end
111                 @projects.push new_prj
112
113                 # check project directory
114                 if not File.exist? "#{@project_root}/#{name}" then
115                         FileUtils.mkdir_p "#{@project_root}/#{name}"
116                 end
117
118                 # write configuration
119                 write_configuration_for_binary_project(name, pkg_name, passwd, os_list)
120
121                 return true
122         end
123
124
125         def add_remote_project( name, server_id)
126         end
127
128
129         # create new job for project
130         # if cannot create, return nil
131         def create_new_job( name, os )
132                 prj = get_project( name )
133                 if prj.nil? then return nil end
134
135                 return prj.create_new_job( os )
136         end
137
138
139         # create new multi build job
140         def create_new_multi_build_job( sub_job_list )
141                 result = MultiBuildJob.new( @server )
142
143                 sub_job_list.each do |job|
144                         result.add_sub_job( job )
145                 end
146
147                 return result
148         end
149
150
151         # create new full job
152         def create_new_full_build_job( )
153                 # create multi job
154                 result = MultiBuildJob.new( @server )
155
156                 # create sub jobs
157                 @projects.each do |prj|
158                         if prj.type != "GIT" then next end      
159                 
160                         prj.os_list.each do |os|
161                                 if not @server.supported_os_list.include? os then next end
162                                 
163                                 new_job = create_new_job( prj.name, os )
164                                 if new_job.nil? then next end
165
166                                 # This make project to build 
167                                 # even though there is a package of same version on pkg-server
168                                 new_job.set_force_rebuild(true)
169         
170                                 # add to multi job
171                                 result.add_sub_job( new_job )   
172                         end     
173                 end
174
175                 return result
176         end
177
178
179         # get project that includes specified pkg name and os
180         # will return [project,os,ver] list
181         def get_projects_from_pkgs(pkgs)
182                 result = []
183                 @projects.each do |prj|
184                         pkgs.each do |pkg|
185                                 name = pkg.package_name
186                                 ver =  pkg.version
187                                 os = pkg.os
188
189                                 # check project provide target package  
190                                 if prj.include_package?(name, ver, os) then
191                                         result.push [prj, os, ver]
192                                         break
193                                 end
194                         end     
195                 end
196
197                 return result
198         end
199
200
201         def get_project_from_package_name(pkg_name)
202                 @projects.each do |prj|
203                         # check project provide target package  
204                         if prj.include_package?(pkg_name) then
205                                 return prj
206                         end
207                 end
208
209                 return nil
210         end
211
212
213         # get project from git repository
214         def get_git_project( repos )
215                 @projects.each { |prj|
216                         if prj.type == "GIT" and prj.repository == repos then 
217                                 return prj 
218                         end
219                 }
220         
221                 return nil
222         end
223
224
225         def create_unnamed_git_project(repos)
226                 name = "UNNAMED_PRJ_#{@projects.count}"
227                 branch = "master"
228                 passwd = nil
229                 os_list = Utils.get_all_OSs()
230                 # add
231                 add_git_project(name , repos, branch, passwd, os_list)
232                 # get
233                 return get_project(name)        
234         end
235
236         protected
237
238         # load and create project       
239         def load_project(name)
240         
241                 # check config file 
242                 config_file = "#{@project_root}/#{name}/build"
243                 if not File.exist? config_file then return nil end
244
245                 # read configuration
246                 type="GIT"
247                 passwd=""
248                 repos="none"
249                 branch="master"
250                 os_list = @server.supported_os_list
251                 rserver_id=nil
252                 pkg_name=nil
253                 File.open( config_file, "r" ) do |f|
254                         f.each_line do |l| 
255                                 idx = l.index("=") + 1
256                                 length = l.length - idx 
257
258                                 if l.start_with?("TYPE=")
259                                         type = l[idx,length].strip
260                                 elsif l.start_with?("PASSWD=")
261                                         passwd = l[idx,length].strip
262                                 elsif l.start_with?("GIT_REPOSITORY=")
263                                         repos = l[idx,length].strip
264                                 elsif l.start_with?("GIT_BRANCH=")
265                                         branch = l[idx,length].strip
266                                 elsif l.start_with?("OS_LIST=")
267                                         os_list = l[idx,length].strip.split(",")
268                                 elsif l.start_with?("REMOTE_SERVER_ID=")
269                                         rserver_id = l[idx,length].strip
270                                 elsif l.start_with?("PACKAGE_NAME=")
271                                         pkg_name = l[idx,length].strip
272                                 else
273                                         next    
274                                 end 
275                         end
276                 end
277
278                 # write back & create project
279                 if type == "GIT" then   
280                         write_configuration(name, repos, branch, passwd, os_list)
281                         new_project = GitBuildProject.new(name, repos, branch, @server, os_list)
282
283                         # read source info
284                         sources_file = "#{@project_root}/#{name}/sources"
285                         if File.exist? sources_file then
286                                 File.open(sources_file, "r") do |f|
287                                         f.each_line do |l|
288                                                 version = l.split(",")[0].strip
289                                                 info = l.split(",")[1].strip
290         
291                                                 new_project.add_source_info( version, info )
292                                         end
293                                 end             
294                         end
295         
296                         # read pkginfo
297                         pkginfo_dir = "#{@project_root}/#{name}/pkginfos"
298                         if not File.exist? pkginfo_dir then FileUtils.mkdir_p pkginfo_dir end
299                         Dir.new(pkginfo_dir).entries.each do |file|
300                                 if file.eql? "." or file.eql? ".." then next end
301                         
302                                 vlen = file.length - ".manifest".length 
303                                 version = file[0,vlen]
304                                 new_project.add_package_info( version, "#{pkginfo_dir}/#{file}" )
305                         end
306
307                 elsif type == "BINARY" then
308                         write_configuration_for_binary_project(name, pkg_name, passwd, os_list)
309                         new_project = BinaryUploadProject.new(name, pkg_name, @server, os_list)
310                 end
311
312
313                 # set passwd if exist
314                 if not passwd.empty? then
315                         new_project.passwd = passwd
316                 end
317
318                 
319                 return new_project
320         end
321
322
323         # write configuration
324         def write_configuration(name, repos, branch, passwd, os_list  )
325                 config_file = "#{@project_root}/#{name}/build"
326                 File.open( config_file, "w" ) do |f|
327                         f.puts "TYPE=GIT"
328                         if not passwd.nil? and not passwd.empty? then
329                                 f.puts "PASSWD=#{passwd}"
330                         end
331                         f.puts "GIT_REPOSITORY=#{repos}"
332                         f.puts "GIT_BRANCH=#{branch}"
333                         f.puts "OS_LIST=#{os_list.join(",")}"
334                 end
335         end
336
337
338         # write configuration
339         def write_configuration_for_binary_project(name, pkg_name, passwd, os_list  )
340                 config_file = "#{@project_root}/#{name}/build"
341                 File.open( config_file, "w" ) do |f|
342                         f.puts "TYPE=BINARY"
343                         if not passwd.nil? and not passwd.empty? then
344                                 f.puts "PASSWD=#{passwd}"
345                         end
346                         f.puts "PACKAGE_NAME=#{pkg_name}"
347                         f.puts "OS_LIST=#{os_list.join(",")}"
348                 end
349         end
350
351
352 end