[Title] change log support
authorjiil.hyoun <jiil.hyoun@samsung.com>
Thu, 27 Sep 2012 12:01:34 +0000 (21:01 +0900)
committerjiil.hyoun <jiil.hyoun@samsung.com>
Thu, 27 Sep 2012 12:01:34 +0000 (21:01 +0900)
[Type] Feature
[Module] Toolchain /
[Priority] Major
[Jira#]
[Redmine#]
[Problem]
[Cause]
[Solution]
[TestCase]

Change-Id: I6cb23795ae843b5298c709e8222b5b005bea5b49

12 files changed:
src/build_server/BinaryUploadProject.rb
src/build_server/BuildServer.rb
src/build_server/BuildServerController.rb
src/build_server/GitBuildJob.rb
src/build_server/RegisterPackageJob.rb
src/build_server/SocketJobRequestListener.rb
src/builder/Builder.rb
src/common/package.rb
src/common/parser.rb
src/pkg_server/distribution.rb
src/pkg_server/packageServer.rb
test/build-cli-04.testcase

index 28f81ea4afff756372ae0994733883f759f09fc1..22278ac24e7410e6ee397a6518d026e166bf5814 100644 (file)
@@ -51,29 +51,64 @@ class BinaryUploadProject < CommonProject
         os = new_name.split(",")[2]
 
                # check file name
-               if @pkg_name != pkg_name then return nil end
+               if @pkg_name != pkg_name then
+                       @server.log.error( "registed name is #{@pkg_name} not #{pkg_name} !", Log::LV_USER)
+                       return nil
+               end
 
                # check os name
-               if not @server.supported_os_list.include? os then return nil end
+               if not @server.supported_os_list.include? os then
+                       @server.log.error( "server not support OS : #{os}", Log::LV_USER)
+                       return nil
+               end
 
                # check package info
                file_path = "#{@server.transport_path}/#{dock}/#{filename}"
-               if not File.exist? file_path then return nil end
+               if not File.exist? file_path then
+                       @server.log.error( "file not exists in #{@server.transport_path}/#{dock}/#{filename}", Log::LV_USER)
+                       return nil
+               end
 
                pkginfo_dir = "#{@server.path}/projects/#{@name}/pkginfos"
                if not File.exist? pkginfo_dir then FileUtils.mkdir_p pkginfo_dir end
                if not Utils.extract_a_file(file_path, "pkginfo.manifest", pkginfo_dir) then
+                       @server.log.error( "pkginfo.manifest file is not exist", Log::LV_USER)
                        return nil
                end
                begin
                        pkginfo =PackageManifest.new("#{pkginfo_dir}/pkginfo.manifest")
                rescue => e
-                       puts e.message
+                       @server.log.error( e.message, Log::LV_USER)
+                       return nil
+               end
+
+               #set up change log
+               change_log = {}
+               begin
+               change_log = Parser.read_changelog "#{pkginfo_dir}/changelog" if File.exist? "#{pkginfo_dir}/changelog"
+               rescue => e
+                       @server.log.error( e.message, Log::LV_USER)
                        return nil
                end
+
+               if not change_log.empty? and pkginfo.packages[0].change_log.empty? then
+                       pkginfo.packages.each {|pkg| pkg.change_log = change_log}
+               end
+
+               if @server.changelog_check and not pkginfo.packages[0].does_change_exist? then
+                       @server.log.error( "change log not found", Log::LV_USER)
+                       return nil
+               end
+
                pkgs =  pkginfo.get_target_packages(os)
-               if pkgs.count != 1 then return nil end
-               if pkgs[0].package_name != @pkg_name then return nil end
+               if pkgs.count != 1 then
+                       @server.log.error( "only one package can upload at one time", Log::LV_USER)
+                       return nil
+               end
+               if pkgs[0].package_name != @pkg_name then
+                       @server.log.error( "package name is #{pkgs[0].package_name} not #{@pkg_name}", Log::LV_USER)
+                       return nil
+               end
 
                new_job = RegisterPackageJob.new( file_path, self, @server )
 
index 0c7e3c61dfc6264e1406080e40a776a41c9d064b..25f83fdd2d5ecf8ed420941c58cefee216f24eb1 100644 (file)
@@ -60,6 +60,7 @@ class BuildServer
        attr_accessor :upgrade
        attr_accessor :remote_pkg_servers
        attr_accessor :pkg_sync_period
+       attr_accessor :changelog_check
 
        CONFIG_ROOT = "#{Utils::HOME}/.build_tools/build_server"
        HOST_OS = Utils::HOST_OS
@@ -109,6 +110,7 @@ class BuildServer
 
                @pkg_sync_period=600
                @upgrade = false
+               @changelog_check = false
        end
 
 
index 4be6726521b7de1b1a2236447b58ae15dbd508de..56d4637a876cc46e5af3412007534729eff56f27 100644 (file)
@@ -1,5 +1,5 @@
 =begin
+
  BuildServerController.rb
 
 Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
@@ -515,10 +515,11 @@ class BuildServerController
                        f.puts "PASSWORD=#{server.test_time}" if server.password != "0000"
                        f.puts "JOB_KEEP_TIME=#{server.keep_time}"
                        f.puts "FTP_ADDR=#{server.ftp_addr}"
-            f.puts "FTP_PORT=#{server.ftp_port}"            
+            f.puts "FTP_PORT=#{server.ftp_port}"
                        f.puts "FTP_USERNAME=#{server.ftp_username}"
                        f.puts "FTP_PASSWD=#{server.ftp_passwd}"
                        f.puts "PKG_SYNC_PERIOD=#{server.pkg_sync_period}"
+                       f.puts "CHANGELOG_CHECK=#{server.changelog_check}"
                end
        end
 
@@ -543,7 +544,8 @@ class BuildServerController
                ftp_port="21"
                ftp_username=""
                ftp_passwd=""
-               pkg_sync_period=600             
+               pkg_sync_period=600
+               changelog_check=false
 
                # read configuration
                server_dir = "#{BuildServer::CONFIG_ROOT}/#{id}"
@@ -590,6 +592,8 @@ class BuildServerController
                                        ftp_passwd = l[idx,length].strip
                                elsif l.start_with?("PKG_SYNC_PERIOD=")
                                        pkg_sync_period = l[idx,length].strip.to_i
+                               elsif l.start_with?("CHANGELOG_CHECK=")
+                                       changelog_check = true if l[idx,length].strip =~ /true/i
                                else
                                        next    
                                end 
@@ -677,9 +681,12 @@ class BuildServerController
                # pkg synchronization
                obj.pkg_sync_period = pkg_sync_period
 
+               # change log setting
+               obj.changelog_check = changelog_check
+
                # save config
                write_server_config( obj )
-               
+
                # create object & return it
                return obj
        end
index 5b1b696e857e92f93c9fd09981bb0beffa10cf07..95eb3c26e976e651c995e626388ed09c2051bb81 100644 (file)
@@ -153,6 +153,24 @@ class GitBuildJob < BuildJob
                        return false
                end
 
+               #set up change log
+               change_log = {}
+               begin
+               change_log = Parser.read_changelog "#{@source_path}/package/changelog" if File.exist? "#{@source_path}/package/changelog"
+               rescue => e
+                       @log.error( e.message, Log::LV_USER)
+                       return false
+               end
+
+               if not change_log.empty? and @pkginfo.packages[0].change_log.empty? then
+                       @pkginfo.packages.each {|pkg| pkg.change_log = change_log}
+               end
+
+               if @server.changelog_check and not @pkginfo.packages[0].does_change_exist? then
+                       @log.error( "change log not found", Log::LV_USER )
+                       return false
+               end
+
                # set up pkgsvr_client
                @pkgsvr_client =  Client.new(@pkgserver_url, @job_working_dir, @log)
 
index 0655ef00aab2bcd63b0fcdfea6fe2289540646c1..b6922889bbbc2e42fb12cd3482e64968cc48d941 100644 (file)
@@ -205,6 +205,11 @@ class RegisterPackageJob
                                return false
                        end
 
+                       if @server.changelog_check and not @pkginfo.packages[0].does_change_exist? then
+                               @log.error( "change log not found", Log::LV_USER )
+                               return false
+                       end
+
                        if @cancel_state != "NONE" then return false end
 
                        if not check_package_version() then
index ae438a98798a844bc7e881c83f0263668c00cc1d..cc66b9f26e0793bcabe09d978d1d24363d86b7f7 100644 (file)
@@ -280,7 +280,7 @@ class SocketJobRequestListener
                # check project
                prj = check_project_exist(prj_name, req)
                if prj.nil? then
-                       raise "Requested project does not exist!"
+                       raise "Requested project \"#{prj_name}\" does not exist!"
                end
 
                # check passwd
@@ -733,7 +733,7 @@ class SocketJobRequestListener
                prj = @parent_server.prjmgr.get_project(project_name)
                if prj.nil? then
                        BuildCommServer.send_begin(req)
-                       req.puts "Error: Requested project does not exist!"
+                       req.puts "Error: Requested project \"#{project_name}\" does not exist!"
                        req.puts "Info: Check project name using \"query\" command option !"
                        BuildCommServer.send_end(req)
                        return nil
index f0087fef4099e446f8745869f2ad2068e99e89f1..4a89fecd216bcdb8be037d882fc4a9efebc9c5a2 100644 (file)
@@ -1,5 +1,5 @@
 =begin
+
  Builder.rb
 
 Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
@@ -184,15 +184,28 @@ class Builder
                        end
                end
 
+               #set up change log
+               change_log = {}
+               begin
+                       change_log = Parser.read_changelog "#{src_path}/package/changelog" if File.exist? "#{src_path}/package/changelog"
+               rescue => e
+                       @log.error( e.message, Log::LV_USER)
+                       return false
+               end
+
+               if not change_log.empty? and pkginfo.packages[0].change_log.empty? then
+                       pkginfo.packages.each {|pkg| pkg.change_log = change_log}
+               end
+
                # set build root
                build_root_dir = @buildroot_dir
                if not File.exist? build_root_dir then
-               FileUtils.mkdir_p build_root_dir
+                       FileUtils.mkdir_p build_root_dir
                end
 
                # create client
                @log.info( "Downloding client is initializing...", Log::LV_USER)
-               cl = Client.new(@pkgserver_url, build_root_dir, @log)
+               cl = Client.new(@pkgserver_url, build_root_dir, @log)
                if clean then 
                        cl.clean(true)
                end
@@ -471,7 +484,9 @@ class Builder
 
                        # write pkginfo.manifest
                        File.open("#{install_dir}/pkginfo.manifest", "w") do |f|
-                               pkg.print_to_file( f )
+                               f.puts pkg
+                               f.puts ""
+                               f.puts pkg.change_log_string
                        end
                end
 
@@ -642,7 +657,7 @@ class Builder
 
                # create pkginfo
                begin
-               pkginfo = PackageManifest.new("#{src_path}/package/pkginfo.manifest")
+               pkginfo = PackageManifest.new("#{src_path}/package/pkginfo.manifest")
                rescue => e
                        @log.error( e.message, Log::LV_USER)
                        return false
index 067342a657788ac1778dcbcc45242d45794bf48b..e54015794d6843fc44d0fc298b917845d8f1b465 100644 (file)
@@ -89,4 +89,25 @@ class Package
     def print_to_file(file)
         file.puts self.to_s
     end
+
+       def change_log_string
+               if @change_log.empty? then return "" end
+
+               string = ""
+               @change_log.sort.each do |list|
+                       string = "* " + list[0] + "\n" + list[1] + "\n" + string
+               end
+               return "#Change log\n" + string
+       end
+
+       def does_change_exist?
+               if not @change_log.empty? and not @change_log[@version].nil? then
+                       return true
+               end
+               return false
+       end
+
+       def get_changes
+               return "#{@package_name} #{@os_list.join(",")} #{@version}\n#{@change_log[@version]}"
+       end
 end
index 8bb863d24686d16588ab10cf1f2388715bd91e13..99ad13725769abc9c5e406ed54c02c5a6d4d1c0a 100644 (file)
@@ -34,284 +34,220 @@ class Parser
     def Parser.read_multy_pkginfo_from (file, only_common = false)
         pkglist = []
                package = nil
+               common_source = ""
+               common_version = ""
+               common_maintainer = ""
+               change_log = {}
+               multi_line = nil
+               change_version = nil
+               change_contents = ""
 
                #file check
 
         File.open file,"r" do |f|
             #variable initialize
                        state = "INIT"
-                       common_source = ""
-                       common_version = ""
-                       common_maintainer = ""
             f.each_line do |l|
-                # separator
-                               if l.strip.empty? then
-                                       #make package and initialize
-                                       if state == "PACKAGE" then
-                                               if not package.package_name.empty? then
-                                                       pkglist.push package
-                                               else
-                                                       raise RuntimeError, "#{file} format is not valid"
-                                               end
-                                       end
-                                       state = "INIT"
-                                       package = nil
-                                       next
-                               end
-                # commant
-                if l.strip.start_with? "#" then next end
-                               #contents
-                               dsic_on = false
-                               case l.strip.split(':')[0].strip
-                               when /^Package/i then
-                                       if only_common then return [common_source, common_version, common_maintainer] end
-                                       # state control
-                                       case state
-                                       when "INIT" then state = "PACKAGE"
-                                       when "COMMON" then state = "PACKAGE"
-                                       when "PACKAGE" then
-                                               if not package.package_name.empty? then
-                                                       pkglist.push package
-                                               else
-                                                       raise RuntimeError, "Package name is not set in \"#{file}\" file"
-                                               end
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
+                               # commant
+                               if l.strip.start_with? "#" then next end
 
-                                       package_name = l.sub(/^[ \t]*Package[ \t]*:[ \t]*/i,"").strip
-                                       if not package_name.empty? then
-                                               package = Package.new(package_name)
-                                               package.source = common_source
-                                               package.version = common_version
-                                               package.maintainer = common_maintainer
-                                       else
-                                               raise RuntimeError, "Package name is not set in \"#{file}\" file"
-                                       end
-                                       disc_on=false
-                               when /^Label/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Label field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.label = l.sub(/^[ \t]*Label[ \t]*:[ \t]*/i,"").strip
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Version/i then
-                                       case state
-                                       when "INIT" , "COMMON" then
-                                               if common_version.empty? then
-                                                       common_version = l.sub(/^[ \t]*Version[ \t]*:[ \t]*/i,"").strip
-                                               else
-                                                       raise RuntimeError, "Version information is conflict in \"#{file}\" file\nIf use Version field in Common section then Package section can't contain Version field"
-                                               end
-                                       when "PACKAGE" then
-                                               if common_version.empty? then
-                                                       package.version = l.sub(/^[ \t]*Version[ \t]*:[ \t]*/i,"").strip
-                                               else
-                                                       raise RuntimeError, "Version information is conflict in \"#{file}\" file\nIf use Version field in Common section then Package section can't contain Version field"
-                                               end
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^OS/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support OS field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then 
-                                               package.os_list = l.sub(/^[ \t]*OS[ \t]*:[ \t]*/i,"").tr(" \t\n\r", "").split(",")
-                                               package.os = package.os_list[0]
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Build-host-os/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Build-host-os field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.build_host_os = l.sub(/^[ \t]*Build-host-os[ \t]*:[ \t]*/i,"").tr(" \t\n\r", "").split(",")
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Maintainer/i then
-                                       case state
-                                       when "INIT" , "COMMON" then
-                                               if common_maintainer.empty? then
-                                                       common_maintainer = l.sub(/^[ \t]*Maintainer[ \t]*:[ \t]*/i,"").strip
-                                               else
-                                                       raise RuntimeError, "Maintainer information is conflict in \"#{file}\" file\nIf use Maintainer field in Common section then Package section can't contain Maintainer field"
+                               field_name = l.split(':')[0].strip
+
+                               case state
+                               when "INIT" then
+                                       case field_name
+                                       when /^$/ then next
+                                       when /^Source$/i  then
+                                               state = "COMMON"
+                                               if common_source.empty? then common_source = l.sub(/^[ \t]*Source[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
                                                end
-                                       when "PACKAGE" then
-                                               if common_maintainer.empty? then
-                                                       package.maintainer = l.sub(/^[ \t]*Maintainer[ \t]*:[ \t]*/i,"").strip
-                                               else
-                                                       raise RuntimeError, "Maintainer information is conflict in \"#{file}\" file\nIf use Maintainer field in Common section then Package section can't contain Maintainer field"
+                                       when /^Version$/i then
+                                               state = "COMMON"
+                                               if common_version.empty? then common_version = l.sub(/^[ \t]*Version[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
                                                end
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Attribute/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Attribute field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.attribute = l.sub(/^[ \t]*Attribute[ \t]*:[ \t]*/i,"").tr(" \t\n\r","").split("|")
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Install-dependency/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Install-dependency field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.install_dep_list = dep_parser l.sub(/^[ \t]*Install-dependency[ \t]*:[ \t]*/i,"").split(',')
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Build-dependency/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Build-dependency field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.build_dep_list = dep_parser l.sub(/^[ \t]*Build-dependency[ \t]*:[ \t]*/i,"").split(',')
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Source-dependency/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Source-dependency field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.source_dep_list = dep_parser l.sub(/^[ \t]*Source-dependency[ \t]*:[ \t]*/i,"").split(',')
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Conflicts/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Conflicts field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.conflicts = dep_parser l.sub(/^[ \t]*Conflicts[ \t]*:[ \t]*/i,"").split(',')
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Source/i then
-                                       case state
-                                       when "INIT" , "COMMON" then
+                                       when /^Maintainer$/i then
                                                state = "COMMON"
-                                               if common_source.empty? then
-                                                       common_source = l.sub(/^[ \t]*Source[ \t]*:[ \t]*/i,"").strip
-                                               else
-                                                       raise RuntimeError, "Source information is conflict in \"#{file}\" file\nIf use Source field in Common section then Package section can't contain Source field"
+                                               if common_maintainer.empty? then common_maintainer = l.sub(/^[ \t]*Maintainer[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
                                                end
-                                       when "PACKAGE" then
-                                               if common_source.empty? then
-                                                       package.source = l.sub(/^[ \t]*Source[ \t]*:[ \t]*/i,"").strip
+                                       when /^Package$/i then
+                                               state = "PACKAGE"
+                                               package_name = l.sub(/^[ \t]*Package[ \t]*:[ \t]*/i,"").strip
+                                               if not package_name.empty? then
+                                                       package = Package.new(package_name)
+                                                       package.source = common_source
+                                                       package.version = common_version
+                                                       package.maintainer = common_maintainer
                                                else
-                                                       raise RuntimeError, "Source information is conflict in \"#{file}\" file\nIf use Source field in Common section then Package section can't contain Source field"
+                                                       raise RuntimeError, "Package name is not set in \"#{file}\" file"
                                                end
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Src-path/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Src-path field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then
-                                               package.src_path = l.sub(/^[ \t]*Src-path[ \t]*:[ \t]*/i,"").strip
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^ORIGIN/ then
-                                       #for compatable
-                                       next
-                               when /^Include/i then
-                                       case state
-                                       when "INIT", "COMMON" then
+                                       when /^\*[ \t]*([0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*)[ \t]*$/ then
+                                               state = "CHANGELOG"
+                                               change_log[change_version] = change_contents.strip if not change_version.nil?
+                                               change_version = $1
+                                               change_contents = ""
+                                       when /^Include$/i then
                                                pfile = File.dirname(file) + "/" + l.sub(/^[ \t]*Include[ \t]*:[ \t]*/i,"").strip
                                                if File.exist? pfile then
-                                                       pkglist = Parser.read_multy_pkginfo_from pfile
+                                                       pkglist = pkglist + (Parser.read_multy_pkginfo_from pfile)
                                                        list = Parser.read_multy_pkginfo_from(pfile, true)
-                                                       common_source = list[0]
-                                                       common_version = list[1]
-                                                       common_maintainer = list[2]
+                                                       common_source = list[0] if common_source.empty?
+                                                       common_version = list[1] if common_version.empty?
+                                                       common_maintainer = list[2] if common_maintainer.empty?
+                                                       change_log = list[3] if change_log.empty?
                                                else
                                                        raise RuntimeError, "Not exist \"#{pfile}\""
                                                end
-                                       when "PACKAGE" then raise RuntimeError, "Not support Include field in Common section in \"#{file}\" file"
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Path/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Path field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.path = l.sub(/^[ \t]*Path[ \t]*:[ \t]*/i,"").strip
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Origin/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Origin field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.origin = l.sub(/^[ \t]*Origin[ \t]*:[ \t]*/i,"").strip
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^SHA256/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support SHA256 field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.checksum = l.sub(/^[ \t]*SHA256[ \t]*:[ \t]*/i,"").strip
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
+                                       else raise RuntimeError, "Can't parse below line in \"#{file}\" file \n\t#{l}"
                                        end
-                                       disc_on=false
-                               when /^Size/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Size field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.size = l.sub(/^[ \t]*Size[ \t]*:[ \t]*/i,"").strip
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
-                                       end
-                                       disc_on=false
-                               when /^Description/i then
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Description field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then package.description = l.sub(/^[ \t]*Description[ \t]*:[ \t]*/i,"")
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
+                               when "COMMON" then
+                                       case field_name
+                                       when /^$/ then state = "INIT"
+                                       when /^Source$/i then
+                                               state = "COMMON"
+                                               if common_source.empty? then common_source = l.sub(/^[ \t]*Source[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
+                                               end
+                                       when /^Version$/i then
+                                               state = "COMMON"
+                                               if common_version.empty? then common_version = l.sub(/^[ \t]*Version[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
+                                               end
+                                       when /^Maintainer$/i then
+                                               state = "COMMON"
+                                               if common_maintainer.empty? then common_maintainer = l.sub(/^[ \t]*Maintainer[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
+                                               end
+                                       else raise RuntimeError, "Can't parse below line in \"#{file}\" file \n\t#{l}"
                                        end
-                                       disc_on=true
-                               when /^C-/ then
-                                       #custom field
-                                       case state
-                                       when "INIT" then raise RuntimeError, "\"Package :\" string must be infront of Package section in \"#{file}\" file"
-                                       when "COMMON" then raise RuntimeError, "Not support Description field in Common section in \"#{file}\" file"
-                                       when "PACKAGE" then
-                                               if package.custom.empty? then
-                                                       package.custom = l.strip
-                                               else
-                                                       package.custom = package.custom + "\n" + l.strip
+                               when "PACKAGE" then
+                                       case field_name
+                                       when /^$/ then
+                                               state = "INIT"
+                                               if not package.package_name.empty? then
+                                                       pkglist.push package
+                                                       package = nil
+                                               else raise RuntimeError, "Package name is not set in \"#{file}\" file"
+                                               end
+                                               multi_line = nil
+                                       when /^Source$/i then
+                                               if common_source.empty? and package.source.empty? then package.source = l.sub(/^[ \t]*Source[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
+                                               end
+                                               multi_line = nil
+                                       when /^Version$/i then
+                                               if common_version.empty? and package.version.empty? then package.version = l.sub(/^[ \t]*Version[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
+                                               end
+                                               multi_line = nil
+                                       when /^Maintainer$/i then
+                                               if common_maintainer.empty? and package.maintainer.empty? then package.maintainer = l.sub(/^[ \t]*Maintainer[ \t]*:[ \t]*/i,"").strip
+                                               else raise RuntimeError, "#{field_name} information is conflict in \"#{file}\" file\nIf use #{field_name} field in Common section then Package section can't contain #{field_name} field"
+                                               end
+                                               multi_line = nil
+                                       when /^OS$/i then
+                                               package.os_list = l.sub(/^[ \t]*OS[ \t]*:[ \t]*/i,"").tr(" \t\n\r", "").split(",")
+                                               package.os = package.os_list[0]
+                                               multi_line = nil
+                                       when /^Label$/i then
+                                               package.label = l.sub(/^[ \t]*Label[ \t]*:[ \t]*/i,"").strip
+                                               multi_line = nil
+                                       when /^Build-host-os$/i then
+                                               package.build_host_os = l.sub(/^[ \t]*Build-host-os[ \t]*:[ \t]*/i,"").tr(" \t\n\r", "").split(",")
+                                               multi_line = nil
+                                       when /^Attribute$/i then
+                                               package.attribute = l.sub(/^[ \t]*Attribute[ \t]*:[ \t]*/i,"").tr(" \t\n\r","").split("|")
+                                               multi_line = nil
+                                       when /^Install-dependency$/i then
+                                               package.install_dep_list = dep_parser l.sub(/^[ \t]*Install-dependency[ \t]*:[ \t]*/i,"").split(',')
+                                               multi_line = nil
+                                       when /^Build-dependency$/i then
+                                               package.build_dep_list = dep_parser l.sub(/^[ \t]*Build-dependency[ \t]*:[ \t]*/i,"").split(',')
+                                               multi_line = nil
+                                       when /^Source-dependency$/i then
+                                               package.source_dep_list = dep_parser l.sub(/^[ \t]*Source-dependency[ \t]*:[ \t]*/i,"").split(',')
+                                               multi_line = nil
+                                       when /^Conflicts$/i then
+                                               package.conflicts = dep_parser l.sub(/^[ \t]*Conflicts[ \t]*:[ \t]*/i,"").split(',')
+                                               multi_line = nil
+                                       when /^Src-path$/i then
+                                               package.src_path = l.sub(/^[ \t]*Src-path[ \t]*:[ \t]*/i,"").strip
+                                               multi_line = nil
+                                       when /^Path$/i then
+                                               package.path = l.sub(/^[ \t]*Path[ \t]*:[ \t]*/i,"").strip
+                                               multi_line = nil
+                                       when /^Origin$/i then
+                                               package.origin = l.sub(/^[ \t]*Origin[ \t]*:[ \t]*/i,"").strip
+                                               multi_line = nil
+                                       when /^SHA256$/i then
+                                               package.checksum = l.sub(/^[ \t]*SHA256[ \t]*:[ \t]*/i,"").strip
+                                               multi_line = nil
+                                       when /^Size$/i then
+                                               package.size = l.sub(/^[ \t]*Size[ \t]*:[ \t]*/i,"").strip
+                                               multi_line = nil
+                                       when /^Description$/i then
+                                               package.description = l.sub(/^[ \t]*Description[ \t]*:[ \t]*/i,"").strip
+                                               multi_line = "Description"
+                                       when /^ORIGIN$/ then #for compatable
+                                               multi_line = nil
+                                               next
+                                       when /^C-/ then
+                                               if package.custom.empty? then package.custom = l.rstrip
+                                               else package.custom = package.custom + "\n" + l.rstrip
+                                               end
+                                               multi_line = nil
+                                       else
+                                               if multi_line.nil? then raise RuntimeError, "Can't parse below line in \"#{file}\" file \n\t#{l}" end
+                                               case multi_line
+                                               when "Description" then package.description = package.description + "\n" + l.rstrip
+                                               else raise RuntimeError, "Can't parse below line in \"#{file}\" file \n\t#{l}"
                                                end
-                                       else raise RuntimeError, "UNKNOWN parser state : #{state}"
                                        end
-                                       disc_on=false
-                               else
-                                       if disc_on and state == "PACKAGE" then
-                                               package.description = package.description + l
+                               when "CHANGELOG" then
+                                       case field_name
+                                       when /^$/ then
+                                               state = "INIT"
+                                               if not change_version.nil? then
+                                                       if change_log[change_version].nil? then change_log[change_version] = change_contents.strip
+                                                       else raise RuntimeError, "change log version is duplicated in \"#{file}\" file \n\t#{l}"
+                                                       end
+                                               end
+                                               change_version = nil
+                                               change_contents = ""
+                                       when /^\*[ \t]*([0-9][0-9]*.[0-9][0-9]*.[0-9][0-9]*)[ \t]*$/ then
+                                               if not change_version.nil? then
+                                                       if change_log[change_version].nil? then change_log[change_version] = change_contents.strip
+                                                       else raise RuntimeError, "change log version is duplicated in \"#{file}\" file \n\t#{l}"
+                                                       end
+                                               end
+                                               change_version = $1
+                                               change_contents = ""
                                        else
-                                               raise RuntimeError, "Can't parse below line in \"#{file}\" file \n\t#{l}"
+                                               change_contents = change_contents + "\n" + l.rstrip
                                        end
+                               else raise RuntimeError, "UNKNOWN state #{field_name}"
                                end
                        end
 
-                       if only_common then return [common_source, common_version, common_maintainer] end
-
-            # check last package
-                       if state == "PACKAGE" then
-                               if not package.package_name.empty? then
-                                       pkglist.push package
-                               else
-                                       raise RuntimeError, "Package name is not set in \"#{file}\" file"
+                       # check last package
+                       if not package.nil? then pkglist.push package end
+                       if not change_version.nil? then
+                               if change_log[change_version].nil? then change_log[change_version] = change_contents.strip
+                               else raise RuntimeError, "change log version is duplicated in \"#{file}\" file \n\t#{l}"
                                end
                        end
+                       pkglist.each {|pkg| pkg.change_log = change_log }
                end
+               if only_common then return [common_source, common_version, common_maintainer, change_log] end
                return pkglist
        end
 
+       def Parser.read_changelog(file)
+               return read_multy_pkginfo_from(file,true)[3]
+       end
+
     def Parser.read_single_pkginfo_from (file)
         return read_multy_pkginfo_from(file)[0]
     end
index d386890f3b1633401603d52242fa6d604f1fcf04..0e6d2449fa5f66ba45d4e4374eca28484b057409 100644 (file)
@@ -1,6 +1,6 @@
 =begin
- distribution.rb 
+
+ distribution.rb
 
 Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
 
@@ -32,10 +32,10 @@ require "parser"
 require "installer"
 
 class Distribution 
-       attr_accessor :name, :location, :server_url, :lock_file_path
+       attr_accessor :name, :location, :server_url, :lock_file_path, :last_sync_changes
 
     # constant
-    PKG_LIST_FILE_PREFIX = "pkg_list_" 
+    PKG_LIST_FILE_PREFIX = "pkg_list_"
        ARCHIVE_PKG_FILE = "archive_pkg_list"
        OS_INFO_FILE = "os_info"
        SNAPSHOT_INFO_FILE = "snapshot.info"
@@ -49,10 +49,11 @@ class Distribution
                @log = pkg_server.log
                @integrity = pkg_server.integrity 
                @lock_file_path = "#{location}/#{LOCK_FILE}"
-               @pkg_hash_os = {}  
-               @archive_pkg_list = [] 
-               @snapshot_hash = [] 
+               @pkg_hash_os = {}
+               @archive_pkg_list = []
+               @snapshot_hash = []
                @support_os_list = []
+               @last_sync_changes = ""
 
                @log.info "Distribution class[#{name}] initialize "
 
@@ -123,7 +124,7 @@ class Distribution
                end
        end
 
-       def generate_snapshot(name, base_snapshot, from_cmd)
+       def generate_snapshot(name, base_snapshot, from_cmd, change_log_string)
                # if name is nil or empty then create uniq name
                if name.nil? or name.empty? then
                        name = Utils.create_uniq_name
@@ -135,7 +136,9 @@ class Distribution
                end
 
                FileUtils.mkdir "#{@location}/snapshots/#{name}"
-               
+               FileUtils.mkdir "#{@location}/changes" if not File.exists? "#{@location}/changes"
+               File.open( "#{@location}/changes/#{name}.log","w") { |f| f.puts change_log_string }
+
                # base_snapshot_path 
                if base_snapshot.empty? then
                        snapshot_path = @location
@@ -190,6 +193,7 @@ class Distribution
                pkg_list_update_flag = false
                archive_update_flag = false
                distribution_update_flag = false
+               changes = []
 
                # reload pkg list from newest pkg list file
                reload_distribution_information()
@@ -207,6 +211,7 @@ class Distribution
                add_os_list = client.support_os_list - @support_os_list
                add_os_list.each do |os|
                        add_os(os)
+                       changes.push "Add OS #{os}"
                        pkg_list_update_flag = true
                end
 
@@ -214,6 +219,7 @@ class Distribution
                        remove_os_list = @support_os_list - client.support_os_list 
                        remove_os_list.each do |os|
                                remove_os(os)
+                               changes.push "Remove OS #{os}"
                                pkg_list_update_flag = true
                        end
                end
@@ -239,7 +245,7 @@ class Distribution
                        end
                end
                
-               # sync archive package 
+               # sync archive package
                update_archive_list = sync_archive_pkg()
 
                # lock
@@ -258,10 +264,10 @@ class Distribution
                        case update_option
                        when "ADD"
                                local_pkg = @pkg_hash_os[os][pkg.package_name]
-                               
+
                                if (not force) and (not local_pkg.nil?) then
                                        # if updated package 'local' package then skip
-                                       if local_pkg.origin.eql? "local" then 
+                                       if local_pkg.origin.eql? "local" then
                                                next
                                        end
 
@@ -270,9 +276,10 @@ class Distribution
                                                next
                                        end
                                end
-                                       
+
                                @pkg_hash_os[os][pkg.package_name] = pkg
-                       when "REMOVE" 
+                               changes.push pkg.get_changes if pkg.does_change_exist?
+                       when "REMOVE"
                                if not force then
                                        if @pkg_hash_os[os][pkg.package_name].origin.eql? "local" then 
                                                next
@@ -280,6 +287,7 @@ class Distribution
                                end
 
                                @pkg_hash_os[os].delete(pkg.package_name)
+                               changes.push "#{pkg.package_name} #{os} removed"
                        else
                                @log.error("Unsupportd update option : #{update_option}", Log::LV_USER)
                                next
@@ -289,6 +297,7 @@ class Distribution
                update_archive_list.each do |pkg|
                        if not @archive_pkg_list.include? pkg then
                                @archive_pkg_list.push pkg
+                               changes.push "Add archive package #{pkg.package_name}"
                                archive_update_flag = true
                        end
                end
@@ -301,13 +310,17 @@ class Distribution
 
                # update archive list file
                if archive_update_flag then
-               write_archive_pkg_list()
+                       write_archive_pkg_list()
                        distribution_update_flag = true
                end
 
-               # unlock 
+               # unlock
                Utils.file_unlock(lock_file)
 
+               if not changes.empty? then
+                       @last_sync_changes = "SYSTEM: sync parents server \n#{changes.join("\n")}"
+               end
+
                return distribution_update_flag
        end
 
index 48dd649e5808f393b1fbd45958131709b3ba9804..146b35f8df3a5db8b94dce834dde9b22d67f0676 100644 (file)
@@ -29,7 +29,7 @@ Contributors:
 require 'fileutils'
 $LOAD_PATH.unshift File.dirname(__FILE__)
 $LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
-$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/build_server" 
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/build_server"
 require "BuildComm"
 require "packageServerLog"
 require "packageServerConfig"
@@ -245,27 +245,35 @@ class PackageServer
                        # email just remote package server
                        # Mail.send_package_registe_mail( msg_list, @id )  
                end
-               
-        # if snapshot mode is true then generate snapshot 
+
+        # if snapshot mode is true then generate snapshot
         if snapshot or test_flag then
                        @log.info "generaging snapshot"
-                       snapshot_name = distribution.generate_snapshot("", "", false)
-               end 
-               
+                       snapshot_name = distribution.generate_snapshot("", "", false, get_changelog_string(registed_package_list) )
+               end
+
                Utils.file_unlock(@lock_file)
                @log.output( "package registed successfully", Log::LV_USER)
 
                return snapshot_name
     end
 
+       def get_changelog_string( package_list )
+               log_list = []
+               package_list.each do |pkg|
+                       if pkg.does_change_exist? then log_list.push pkg.get_changes end
+               end
+               return log_list.uniq.join("\n")
+       end
+
        def generate_snapshot( snpashot_name, dist_name, base_snapshot )
                @log.info "generating snapshot"
                distribution = get_distribution( dist_name )
 
                @lock_file = Utils.file_lock(distribution.lock_file_path)
 
-               snapshot_name = distribution.generate_snapshot( snpashot_name, base_snapshot, true)
-               
+               snapshot_name = distribution.generate_snapshot( snpashot_name, base_snapshot, true, "SYSTEM:")
+
                Utils.file_unlock(@lock_file)
                
                return snapshot_name
@@ -278,13 +286,13 @@ class PackageServer
                if distribution.server_url.empty? then 
                        @log.error( "This distribution has not remote server", Log::LV_USER) 
                        return
-               end 
+               end
 
                ret = distribution.sync(mode)
-               if ret then 
-                       distribution.generate_snapshot("", "", false)
+               if ret then
+                       distribution.generate_snapshot("", "", false, distribution.last_sync_changes)
                end
-               
+
                @log.output( "package server [#{@id}]'s distribution [#{dist_name}] has been synchronized.", Log::LV_USER )
        end
 
@@ -331,7 +339,7 @@ class PackageServer
                dist.add_os(os)
 
                @log.info "generaging snapshot"
-               dist.generate_snapshot("", "", false)
+               dist.generate_snapshot("", "", false, "Add #{os} Package server")
 
                Utils.file_unlock(@lock_file)
                @log.output( "package server add os [#{os}] successfully", Log::LV_USER )
@@ -416,7 +424,7 @@ class PackageServer
        
                # generate snapshot     
                @log.info "generaging snapshot"
-               distribution.generate_snapshot("", "", false)
+               distribution.generate_snapshot("", "", false, "SYSTEM: Package \"#{pkg_name_list.join(", ")}\" is(are) removed in #{os} server")
 
                Utils.file_unlock(lock_file)
                @log.output( "package removed successfully", Log::LV_USER )
@@ -671,7 +679,7 @@ class PackageServer
                        end
                        
                        distribution.sync(false)
-                       distribution.generate_snapshot("", "", false)
+                       distribution.generate_snapshot("", "", false, distribution.last_sync_changes)
                else
                        @log.info "generate package server do not using remote package server"
        
index e990744f4ef1378d5a059cb6c5d1eab8434caaac..f6b338ecc798b8b514f64f9adfa2a1a938a6e272 100644 (file)
@@ -3,5 +3,5 @@
 ../build-cli build -N non_exist_project -d 127.0.0.1:2223 -o ubuntu-32
 #POST-EXEC
 #EXPECT
-Error: Requested project does not exist!
+Error: Requested project "non_exist_project" does not exist!
 Info: Check project name using "query" command option !