Initialize
authorSungho Park <chywoo.park@samsung.com>
Mon, 27 Feb 2012 12:24:14 +0000 (21:24 +0900)
committerSungho Park <chywoo.park@samsung.com>
Mon, 27 Feb 2012 12:24:14 +0000 (21:24 +0900)
82 files changed:
AUTHORS [new file with mode: 0644]
LICENSE [new file with mode: 0644]
NOTICE [new file with mode: 0644]
README [new file with mode: 0644]
build-cli [new file with mode: 0755]
build-svr [new file with mode: 0755]
package/.log [new file with mode: 0644]
package/build.linux [new file with mode: 0755]
package/pkginfo.manifest [new file with mode: 0644]
pkg-build [new file with mode: 0755]
pkg-clean [new file with mode: 0755]
pkg-cli [new file with mode: 0755]
pkg-svr [new file with mode: 0755]
src/build_server/BuildClientOptionParser.rb [new file with mode: 0644]
src/build_server/BuildComm.rb [new file with mode: 0644]
src/build_server/BuildJob.rb [new file with mode: 0644]
src/build_server/BuildServer.rb [new file with mode: 0644]
src/build_server/BuildServerController.rb [new file with mode: 0644]
src/build_server/BuildServerOptionParser.rb [new file with mode: 0644]
src/build_server/GitBuildJob.rb [new file with mode: 0644]
src/build_server/JobLog.rb [new file with mode: 0644]
src/build_server/LocalBuildJob.rb [new file with mode: 0644]
src/build_server/RemoteBuildJob.rb [new file with mode: 0644]
src/build_server/SocketJobRequestListener.rb [new file with mode: 0644]
src/builder/Builder.rb [new file with mode: 0644]
src/builder/CleanOptionParser.rb [new file with mode: 0644]
src/builder/optionparser.rb [new file with mode: 0644]
src/common/PackageManifest.rb [new file with mode: 0644]
src/common/Version.rb [new file with mode: 0644]
src/common/dependency.rb [new file with mode: 0644]
src/common/log.rb [new file with mode: 0644]
src/common/mail.rb [new file with mode: 0644]
src/common/mailConfig.rb [new file with mode: 0644]
src/common/package.rb [new file with mode: 0644]
src/common/parser.rb [new file with mode: 0644]
src/common/utils.rb [new file with mode: 0644]
src/pkg_server/client.rb [new file with mode: 0644]
src/pkg_server/clientOptParser.rb [new file with mode: 0644]
src/pkg_server/distribution.rb [new file with mode: 0644]
src/pkg_server/downloader.rb [new file with mode: 0644]
src/pkg_server/installer.rb [new file with mode: 0644]
src/pkg_server/packageServer.rb [new file with mode: 0644]
src/pkg_server/packageServerLog.rb [new file with mode: 0644]
src/pkg_server/serverConfig.rb [new file with mode: 0644]
src/pkg_server/serverOptParser.rb [new file with mode: 0644]
test/a/a [new file with mode: 0644]
test/a/package/build.linux [new file with mode: 0755]
test/a/package/pkginfo.manifest [new file with mode: 0644]
test/b/b [new file with mode: 0644]
test/b/package/build.linux [new file with mode: 0755]
test/b/package/pkginfo.manifest [new file with mode: 0644]
test/c/c [new file with mode: 0644]
test/c/package/build.linux [new file with mode: 0755]
test/c/package/pkginfo.manifest [new file with mode: 0644]
test/pkg-list [new file with mode: 0644]
test/pkginfo.manifest [new file with mode: 0644]
test/test_bserver.rb [new file with mode: 0755]
test/test_bserver2-1.rb [new file with mode: 0755]
test/test_bserver2.rb [new file with mode: 0755]
test/test_bserver2c.rb [new file with mode: 0755]
test/test_bserver3.rb [new file with mode: 0755]
test/test_bserver3c.rb [new file with mode: 0755]
test/test_client.rb [new file with mode: 0755]
test/test_downloader.rb [new file with mode: 0755]
test/test_installer.rb [new file with mode: 0755]
test/test_pkglist_parser.rb [new file with mode: 0755]
test/test_server [new file with mode: 0755]
test/test_server.rb [new file with mode: 0755]
test/test_server_pkg_file/smart-build-interface_1.20.1.tar.gz [new file with mode: 0644]
test/test_server_pkg_file/smart-build-interface_1.20.1_linux.zip [new file with mode: 0644]
test/test_utils.rb [new file with mode: 0755]
test/tpkg/.log [new file with mode: 0644]
test/tpkg/package/build.linux [new file with mode: 0755]
test/tpkg/package/pkgfour.install [new file with mode: 0644]
test/tpkg/package/pkgfour.remove [new file with mode: 0644]
test/tpkg/package/pkginfo.manifest [new file with mode: 0644]
test/tpkg/package/pkgone.install [new file with mode: 0644]
test/tpkg/package/pkgone.remove [new file with mode: 0644]
test/tpkg/package/pkgthree.install [new file with mode: 0644]
test/tpkg/package/pkgthree.remove [new file with mode: 0644]
test/tpkg/package/pkgtwo.install [new file with mode: 0644]
test/tpkg/package/pkgtwo.remove [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..9589ae0
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,5 @@
+DongHee Yang <donghee.yang@samsung.com>
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+HyunGoo Kang <hyungoo1.kang@samsung.com>
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..4297ee3
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..e54ec3f
--- /dev/null
+++ b/README
@@ -0,0 +1,318 @@
+Tizen SDK Development Guide
+
+
+Contents
+========================================
+
+1 Introduction
+2 Setup Build Environment
+2.1 Linux(Ubuntu)
+2.1.1 Install Tizen SDK
+2.1.2 Install Ruby
+2.1.3 Install Packages needed by DIBS
+2.1.4 Install Pre-Requisite Packages
+2.1.5 More
+2.2 Windows
+2.2.1 Install Tizen SDK
+2.2.2 Install Ruby
+2.2.3 Install Packages needed by DIBS
+2.2.4 Install MSYS GIT
+2.2.5 More
+3 Simple Build and Test
+3.1 Build Package
+3.2 Install Package
+3.3 Launch your own SDK
+4 More DIBS commands
+4.1 List Up Available Packages
+4.2 Update Package List
+4.3 Upgrade Packages
+4.4 Install SDK
+
+
+1 Introduction
+========================================
+
+Tizen SDK is composed of many separated packages which are has their own dependencies. And DIBS(Distributed Intelligent Build System) is the build system designed for building that kind of complexity. It provides various features.
+* Has own packaging system and packaging interface
+* Provides distributed package server/build Server
+* Provides Automatic dependency checker/resolver
+* Provides client/server tools which are easy to use
+This guides will show how to build Tize SDK packages using DIBS
+
+
+2 Setup Build Environment
+========================================
+
+2.1 Linux(Ubuntu)
+
+2.1.1 Install Tizen SDK
+Install the SDK first
+
+2.1.2 Install Ruby
+To use DIBS, you have to install Ruby 1.8.7
+
+    $ sudo apt-get install ruby
+
+Higher version of Ruby is not tested yet!
+
+2.1.3 Install Packages needed by DIBS
+
+    $ sudo apt-get install wget zip unzip
+
+2.1.4 Install Pre-Requisite Packages
+To build or develop SDK , you have to install following packages
+* For emulator development
+    bcc bison flex autoconf gcc libglu1-mesa-dev libsdl1.2-dev libgtk2.0-dev libsdl-image1.2-dev libsdl-gfx1.2-dev debhelper libxml2-dev libasound2-dev libx11-dev zlib1g-dev uuid-dev libv4l-dev
+* GDB 7.2
+    quilt libncurses5-dev libexpat1-dev libreadline-dev mingw32(only for building windows version)
+* GCC 4.5
+    quilt texinfo bison flex mingw32(only for building windows version)
+
+    $ sudo apt-get install {pre-requisite packages}
+    
+2.1.5 More
+For your convenience,
+* Add DIBS path to $PATH. Edit shell configuration. ex) .bashrc
+
+    $ export PATH={SDK Install dir}/dev-tools:$PATH
+
+2.2 Windows
+
+2.2.1 Install Tizen SDK
+Install the SDK first
+
+2.2.2 Install Ruby
+* You can download Ruby binary at ..
+    ftp://ftp.ruby-lang.org/pub/ruby/binaries/mswin32/ruby-1.8.7-i386-mswin32.zip 
+    http://rubyforge.org/frs/download.php/75679/rubyinstaller-1.8.7-p357.exe 
+
+2.2.3 Install Packages needed by DIBS
+* Login MinGW provided by Tizen SDK. Execute following windows BAT file.
+
+    {Tizen-Install Dir}/MinGW/msys/1.0/msys.bat
+
+* Execute the following commands on MinGW environment
+
+    $ mingw-get.exe update
+    $ mingw-get.exe install msys-wget
+    $ mingw-get.exe install msys-zip
+    $ mingw-get.exe install msys-unzip
+
+2.2.4 Install MSYS GIT
+* Download the MSYS binary
+    http://msysgit.googlecode.com/files/Git-1.7.9-preview20120201.exe
+
+* Install it
+
+2.2.5 More
+For your convenience,
+* Add "/usr/bin/ruby" shell script
+
+    #!/bin/sh
+    {ruby install dir}/bin/ruby.exe $@
+
+    ex)
+
+        #!/bin/sh
+        /c/Ruby187/bin/ruby.exe $@
+
+* Add "/usr/bin/git" shell script
+
+    #!/bin/sh
+    {MSYS GIT install dir}/bin/ruby.exe $@
+
+    ex)
+
+        #!/bin/sh
+        /c/Program\ Files/Git/bin/it.exe $@
+
+* Add DIBS path to $PATH. Edit shell configuration. ex) /etc/profile
+
+    $ export PATH={SDK Install dir}/dev-tools:$PATH
+
+
+3 Simple Build and Test
+========================================
+
+If you downloaded a SDK package source and modified it, then you want to build it and apply it to Tizen SDK. Here is the simple process to do it.
+
+3.1 Build Package
+Building a SDK package is very simple. Here is the command for buiding package.
+
+    ## pkg-build [-u <package server url>] [-o <os>] [-c <clean>] [-r <reverse build dependency check>]
+    ## -u : Package server URL which contains binary and development packages.
+    ##      If ommited, it will use previous server URL.
+    ## -o : Target OS(linux or windows)
+    ## -c : Clean build""
+    ##      If set, start build after downloading all dependent packages
+    ##      If not set, it will not download dependent packages if already downloaded
+    ## -r : Check reverse-build-dependency
+    ##      This option will check that the packages which depend on me can be built
+
+And Here are simple steps
+    1. Move to source directory
+        ex) 
+        
+            $ cd ~/project/common-eplugin
+
+    2. Type the command
+        ex) 
+            
+            $ pkg-build -u http://172.21.17.55/dibs/unstable
+
+    3. Now you can see the package files( *.zip, *.tar.gz ) in your source directory
+
+3.2 Install Package
+Installing a SDK package is also very simple. Here is the command for installing package files
+
+    ## pkg-cli install-file -p <package file path> [-l <location>] [-f]
+    ## -p : Binary package file(*.zip) path which you want to install
+    ## -l : Install root location of target SDK
+    ##      If omitted, current working directory path will be set
+    ## -f : Install the package by force
+    ##      This option will allow installing the package that has lower or equal version compare to installed 
+
+Now let's assume that you have just finished building and have a Tizen SDK installation on '~/tizen_sdk'
+    1. Just type the command
+        ex) 
+    
+            $ pkg-cli install-file -p common-eplugin_0.20.6_linux.zip -l ~/tizen_sdk
+
+3.3 Launch your own SDK
+Now you can check your modifications. Lauch your SDK!!
+    1. type the following command or use the short-cut for launching Tizen SDK.
+        ex) 
+        
+            $ ~/tizen_sdk/IDE/startup.sh
+
+
+4 More DIBS commands
+========================================
+
+There are more useful commands provided
+
+4.1 List Up Available Packages
+You can list up available packages of server.
+
+    ## pkg-cli list-rpkg [-o <os>] [-u <package server url>] 
+    ## -o : Target OS(linux or windows)
+    ## -u : Package server URL which contains binary and development packages.
+    ##      If ommited, it will use previous server URL.
+
+    1. List up packages
+        ex) 
+            
+            $ pkg-cli update -u http://172.21.17.55/dibs/unstable_release
+
+        ex) 
+            
+            $ pkg-cli list-rpkg
+
+    2. List up packages with updating
+        ex) 
+        
+            $ pkg-cli list-rpkg -u http://172.21.17.55/dibs/unstable_release
+
+You can list up packages of your install directory
+
+    ## pkg-cli list-lpkg [-l <locatio>] 
+    ## -l : Install root location of target SDK
+    ##      If omitted, current working directory path will be set
+
+    1. List up packages
+        ex) 
+        
+            $ pkg-cli list-lpkg -l ~/tizen_sdk
+
+4.2 Update Package List
+You should have package list of server in your host before listing, installing and downloading packages. So, if you want to install the latest package, then you should update your package list before installing.
+
+    ## pkg-cli update [-u <package server url>] 
+    ## -u : Package server URL which contains binary and development packages.
+    ##      If ommited, it will use previous server URL.
+
+    1. Update package list from server
+        ex) 
+
+            $ pkg-cli update -u http://172.21.17.55/dibs/unstable_release
+
+    2. Install / download packages from server
+        ex) 
+
+            $ pkg-cli install -p nativeapp-eplugin -l ~/tizen_sdk
+
+        ex) 
+
+            $ pkg-cli install -p unittest-eplugin -l ~/tizen_sdk
+
+        ex) 
+
+            $ pkg-cli download -p base-ide-product -l ~/downloads
+
+    3. If package is updated on server and you want to use is, you should update your package list. If you do not set the server url, it will be set previous server URL.
+        ex) 
+
+            $ pkg-cli update
+
+        ex) 
+
+            $ pkg-cli install -p nativeapp-eplugin -l ~/tizen_sdk
+        
+4.3 Upgrade Packages
+You can upgrade your installed packages from server.
+
+    ## pkg-cli upgrade -l <location> -u <package server url>
+    ## -u : Package server URL which contains binary and development packages.
+    ##      If ommited, it will use previous server URL.
+    ## -l : Install root location of target SDK
+    ##      If omitted, current working directory path will be set
+
+    1. Check package for upgrading
+        ex)
+
+            $ pkg-cli update -u http://172.21.17.55/dibs/unstable_release
+            $ pkg-cli check-upgrade -l ~/tizen_sdk
+
+    2. Upgrade packages
+        ex)
+
+            $ pkg-cli upgrade -l ~/tizen_sdk
+
+    3. Upgrade packages with updating
+        ex)
+        
+            $ pkg-cli upgrade -l ~/tizen_sdk -u http://172.21.17.55/dibs/unstable_release
+
+    4. If you want to upgrade specific package, you can upgrade it as installing
+        ex)
+
+            $ pkg-cli install -p common-eplugin -l ~/tizen_sdk -u http://172.21.17.55/dibs/unstable_release
+
+4.4 Install SDK
+You can also install new SDK using the network install command. Originally this command is used for installing packages by network. But you can set "TIZEN-SDK" as package name, all Tizen SDK packages will be installed.
+
+    ## pkg-cli install -p <package name> [-u <package server url>] [-l <location>] [-t] [-f]
+    ## -p : Binary package name which you want to install
+    ## -u : Package server URL which contains binary and development packages.
+    ##      If ommited, it will use previous server URL.
+    ## -l : Install root location of target SDK
+    ##      If omitted, current working directory path will be set
+    ## -t : Install the package with all dependent packages 
+    ## -f : Install the package by force
+    ##      This option will allow installing the package that has lower or equal version compare to installed 
+
+    1. Install "TIZEN-SDK" by network to new location("~/tizen_sdk2")
+        ex) 
+
+            $ pkg-cli install -p TIZEN-SDK -l ~/tizen_sdk2 -t
+
+    2. Change Tizen SDK configuration
+        ex) 
+
+            $ echo "TIZEN_SDK_INSTALLED_PATH=/home/{username}/tizen_sdk2" > ~/.TizenSDK/tizensdkpath
+
+    3. Launch your SDK!
+        ex) 
+
+            $ ~/tizen_sdk2/IDE/startup.sh
+
diff --git a/build-cli b/build-cli
new file mode 100755 (executable)
index 0000000..425c32a
--- /dev/null
+++ b/build-cli
@@ -0,0 +1,117 @@
+#!/usr/bin/ruby -d
+
+=begin
+ build-cli
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require "socket"
+require 'fileutils'
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/build_server"
+require "utils"
+require "BuildClientOptionParser"
+require "BuildComm"
+
+#option parsing 
+option = option_parse
+
+# if "--os" is not specified, use host os type
+if option[:os].nil? then 
+    option[:os] = Utils::HOST_OS
+else 
+    if not option[:os] =~ /^(linux|windows|darwin)$/ then 
+        puts "We have no plan to Buld OS \"#{option[:os]}\" \n please check your option OS "
+        exit 1
+    end
+end
+
+if option[:domain].nil? then
+       option[:domain] = "172.21.17.46"
+end
+
+if option[:port].nil? then
+       option[:port] = 2222
+end
+
+begin
+       case option[:cmd] 
+       when "build" 
+               client = BuildCommClient.create( option[:domain], option[:port])
+               if not client.nil? then
+                       client.send "BUILD,GIT,#{option[:git]},#{option[:commit]},#{option[:os]},,#{option[:async]}"
+                       client.print_stream
+                       client.terminate
+               end
+       when "resolve"
+               client = BuildCommClient.create( option[:domain], option[:port])
+               if not client.nil? then
+                       client.send "RESOLVE,GIT,#{option[:git]},#{option[:commit]},#{option[:os]},,#{option[:async]}" 
+                       client.print_stream
+                       client.terminate
+               end
+       when "query"
+               # SYSTEM INFO
+               client = BuildCommClient.create( option[:domain], option[:port])
+               if not client.nil? then
+                       client.send "QUERY,SYSTEM" 
+                       result0 = client.receive_data()
+                       if result0.nil? then
+                               client.terminate
+                               exit(-1)
+                       end
+                       result0 = result0[0].split(",").map { |x| x.strip }
+                       puts "HOST-OS: #{result0[0]}"
+                       puts "MAX_WORKING_JOBS: #{result0[1]}"
+                       client.terminate
+               end
+
+               # JOB INFO
+               client = BuildCommClient.create( option[:domain], option[:port])
+               if not client.nil? then
+                       client.send "QUERY,JOB"
+                       result1 = client.receive_data()
+                       if result0.nil? then
+                               client.terminate
+                               exit(-1)
+                       end
+                       puts "* JOB *"
+                       for item in result1
+                               tok = item.split(",").map { |x| x.strip }
+                               puts "#{tok[1]} #{tok[0]} #{tok[2]}"    
+                       end
+               end
+
+       else
+               raise RuntimeError, "input option incorrect : #{option[:cmd]}"
+       end
+
+rescue => e
+       puts e.message
+       exit(-1)
+end
+
+exit 0
diff --git a/build-svr b/build-svr
new file mode 100755 (executable)
index 0000000..f1ddaf9
--- /dev/null
+++ b/build-svr
@@ -0,0 +1,108 @@
+#!/usr/bin/ruby -d 
+
+=begin
+ build-svr
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'fileutils'
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/build_server"
+require "utils"
+require "BuildServerOptionParser"
+require "BuildServerController"
+
+#option parsing 
+begin
+       option = option_parse
+rescue => e
+       puts "Option parse error"
+       puts e.message
+       exit 0
+end
+
+
+# if "--os" is not specified, use host os type
+if option[:os].nil? then
+    host_os = `uname -s`.strip
+    case host_os
+    when "Linux"
+        option[:os] = "linux"
+    when /MINGW32.*/
+        option[:os] = "windows"
+    when "Darwin"
+        option[:os] = "darwin"
+    else
+        if not option[:os] =~ /^(linux|windows|darwin)$/ then 
+            puts "We have no plan to Buld OS \"#{option[:os]}\" \n please check your option OS "
+            exit 1
+        end
+    end 
+else
+    if not option[:os] =~ /^(linux|windows|darwin)$/ then 
+        puts "We have no plan to Buld OS \"#{option[:os]}\" \n please check your option OS "
+        exit 1
+    end
+end 
+
+
+
+begin
+       case option[:cmd] 
+       when "create" 
+               BuildServerController.create_server( option[:name], Utils::WORKING_DIR, option[:url], option[:domain], option[:pid] )
+       when "remove"
+               BuildServerController.remove_server( option[:name] ) 
+       when "start"
+               BuildServerController.start_server( option[:name], option[:port] ) 
+       when "build"
+               if not option[:git].nil? then
+                       if option[:resolve] then
+                               BuildServerController.resolve_git( option[:name], option[:git], option[:commit], option[:os], nil )
+                       else
+                               BuildServerController.build_git( option[:name], option[:git], option[:commit], option[:os], nil )
+                       end
+               elsif not option[:local].nil? then
+                       if option[:resolve] then
+                               BuildServerController.resolve_local( option[:name], option[:local], option[:os], nil )
+                       else
+                               BuildServerController.build_local( option[:name], option[:local], option[:os], nil )
+                       end
+               else
+                       RuntimeError "Wrong build options are specified!"
+               end
+       when "add"
+               BuildServerController.add_friend_server( option[:name], option[:domain], option[:port] ) 
+       else
+               raise RuntimeError, "input option incorrect : #{option[:cmd]}"
+       end
+
+       exit 0
+rescue => e
+       puts e.message
+end
+
+
diff --git a/package/.log b/package/.log
new file mode 100644 (file)
index 0000000..d739a34
--- /dev/null
@@ -0,0 +1,4 @@
+# Logfile created on Mon Feb 06 23:18:31 +0900 2012 by logger.rb/22285
+I, [2012-02-06T23:18:31.266112 #30127]  INFO -- : option parsing start
+I, [2012-02-06T23:18:31.266200 #30127]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-06T23:18:31.266322 #30127]  INFO -- : option parsing end
diff --git a/package/build.linux b/package/build.linux
new file mode 100755 (executable)
index 0000000..7ff849a
--- /dev/null
@@ -0,0 +1,34 @@
+#!/bin/sh -xe
+# clean
+clean()
+{
+       rm -rf $SRCDIR/*.zip
+       rm -rf $SRCDIR/*.tar.gz
+}
+
+# build
+build() 
+{
+       echo "build"
+}
+
+# install
+install() 
+{
+       BIN_DIR=$SRCDIR/package/dibs.package.${BUILD_TARGET_OS}/data/dev_tools
+       DOC_DIR=$SRCDIR/package/dibs.package.${BUILD_TARGET_OS}/data/dev_tools/doc
+       mkdir -p $BIN_DIR
+       mkdir -p $DOC_DIR
+       cp -f $SRCDIR/pkg-* $BIN_DIR/
+       cp -f $SRCDIR/build-* $BIN_DIR/
+       cp -rf $SRCDIR/src $BIN_DIR/
+       cp -rf $SRCDIR/src $BIN_DIR/
+       cp -f $SRCDIR/AUTHORS $DOC_DIR/
+       cp -f $SRCDIR/LICENSE $DOC_DIR/
+       cp -f $SRCDIR/NOTICE $DOC_DIR/
+}
+
+
+$1
+echo "$1 success"
+
diff --git a/package/pkginfo.manifest b/package/pkginfo.manifest
new file mode 100644 (file)
index 0000000..3e172a3
--- /dev/null
@@ -0,0 +1,15 @@
+Package : dibs
+Version : 0.20.7
+Maintainer : taejun ha<taejun.ha@samsung.com>, jiil hyoun <jiil.hyoun@samsung.com>, <donghyouk.yang@samsung.com>, donghee yang< donghee.yang@samsung.com >
+Description : Distribute Inteligent Build System
+OS : linux
+Build-host-os : linux
+Source : dibs
+
+Package : dibs
+Version : 0.20.7
+Maintainer : taejun ha<taejun.ha@samsung.com>, jiil hyoun <jiil.hyoun@samsung.com>, <donghyouk.yang@samsung.com>, donghee yang< donghee.yang@samsung.com >
+Description : Distribute Inteligent Build System
+OS : windows
+Build-host-os : linux
+Source : dibs
diff --git a/pkg-build b/pkg-build
new file mode 100755 (executable)
index 0000000..22b58f3
--- /dev/null
+++ b/pkg-build
@@ -0,0 +1,86 @@
+#!/usr/bin/ruby 
+
+=begin
+ pkg-build
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/pkg_server"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/builder"
+require "utils"
+require "packageServer"
+require "Builder"
+require "optionparser"
+
+option = parse
+
+#generate server when local package server is not set
+
+# if "--os" is not specified, use host os type
+if option[:os].nil? then
+       option[:os] = Utils::HOST_OS
+else 
+    if not option[:os] =~ /^(linux|windows|darwin)$/ then 
+        puts "We have no plan to Buld OS \"#{option[:os]}\" \n please check your option OS "
+        exit 1
+    end
+end
+
+path = Dir.pwd
+if not File.exist? "package" then 
+    puts "current dirctory \"#{path}\" is not package root directory"
+    exit 1
+end 
+
+# if url specified
+if not option[:url].nil? then
+       begin
+       builder = Builder.get("default") 
+               if builder.pkgserver_url != option[:url] then
+                       puts "Package server URL has been changed! Creating new builder..."
+               builder = Builder.create("default", option[:url], nil)  
+               end
+       rescue
+               puts "Default builder does not exist! Creating new builder..."
+       builder = Builder.create("default", option[:url], nil)  
+       end
+else # if url is not specified
+       begin 
+       builder = Builder.get("default")  
+       rescue
+               puts "Default builder does not exist! Creating new builder..."
+       builder = Builder.create("default", "http://172.21.111.132/pkgserver/unstable",nil)  
+       end
+end 
+
+#build project
+if not builder.build( Utils::WORKING_DIR, option[:os], option[:clean], option[:rev], [], []) then
+       puts "Build Failed!"
+else
+       puts "Build Succeeded!"
+end
+
diff --git a/pkg-clean b/pkg-clean
new file mode 100755 (executable)
index 0000000..de48dce
--- /dev/null
+++ b/pkg-clean
@@ -0,0 +1,62 @@
+#!/usr/bin/ruby 
+
+=begin
+ pkg-clean
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/pkg_server"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/builder"
+require "utils"
+require "packageServer"
+require "Builder"
+require "CleanOptionParser"
+
+path = Dir.pwd
+if not File.exist? "package" then 
+    puts "current dirctory \"#{path}\" is not package root directory"
+    exit 1
+end 
+
+option = parse
+
+#generate server when local package server is not set
+
+begin 
+       builder = Builder.get("default")  
+rescue
+       puts "Default builder does not exist! Creating new builder..."
+       builder = Builder.create("default", "http://172.21.111.132/pkgserver/unstable",nil)  
+end
+
+#build project
+if not builder.clean( Utils::WORKING_DIR ) then
+       puts "Clean failed!"
+else
+       puts "Clean succeeded!"
+end
+
diff --git a/pkg-cli b/pkg-cli
new file mode 100755 (executable)
index 0000000..2e0f21e
--- /dev/null
+++ b/pkg-cli
@@ -0,0 +1,178 @@
+#!/usr/bin/ruby 
+
+=begin
+ pkg-cli
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'fileutils'
+require 'logger'
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/pkg_server"
+
+#library
+require "utils"
+require "clientOptParser"
+require "client"
+require "packageServer"
+
+#set global variable
+@WORKING_DIR = nil
+
+$log = Logger.new('.log', 'monthly')
+
+#option parsing 
+begin
+       option = option_parse
+rescue => e
+       # if option parse error print help message
+    $log.error "option parsing error"
+       system "#{__FILE__} help"
+       exit 0
+end
+
+#if "--os" is not specfied, use host os type
+if option[:os].nil? then
+       system_type = `uname -s`
+       case system_type.strip
+    when "Linux" then
+               option[:os] = "linux"
+       when /MINGW32.*/ then
+               option[:os] = "windows"
+       when "Darwin" then
+               option[:os] = "darwin"
+       else
+               raise RuntimeError, "Unknown OS type : #{system_type}"
+       end
+end
+
+case option[:cmd] 
+when "update" then
+    client = Client.new( option[:url], nil, nil )
+    client.update()
+when "clean" then
+    client = Client.new( nil, option[:loc], nil )
+    client.clean(option[:f])
+when "download" then
+    client = Client.new( option[:url], option[:loc], nil )
+    if not option[:url].nil? then
+        client.update()
+    end
+       file_loc = client.download( option[:pkg], option[:os], option[:t] )
+when "upload" then
+    client = Client.new( nil, nil, nil )
+       result = client.upload( option[:alias], option[:id], option[:binpkg], option[:srcpkg], false )
+    if not result.nil? then
+        puts result
+    end
+when "source" then    
+    client = Client.new( option[:url], option[:loc], nil )
+    if not option[:url].nil? then
+        client.update()
+    end
+    client.download_source( option[:pkg], option[:os] )
+when "install" then
+    client = Client.new( option[:url], option[:loc], nil )
+    if not option[:url].nil? then
+        client.update()
+    end
+       client.install( option[:pkg], option[:os], option[:t], option[:f] ) 
+when "install-file" then
+    client = Client.new( nil, option[:loc], nil )
+       client.install_local_pkg( option[:pkg], option[:f] ) 
+when "uninstall" then
+    client = Client.new( nil, option[:loc], nil )
+    client.uninstall( option[:pkg], option[:t] )
+when "upgrade" then
+    client = Client.new( option[:url], option[:loc], nil )
+    if not option[:url].nil? then
+        client.update()
+    end
+    client.upgrade( option[:os], option[:t] )
+when "check-upgrade" then
+    client = Client.new( option[:url], option[:loc], nil )
+    if not option[:url].nil? then
+        client.update()
+    end
+    client.check_upgrade( option[:os] )
+when "show-rpkg" then
+    client = Client.new( option[:url], nil, nil )
+    if not option[:url].nil? then
+        client.update()
+    end
+       puts client.show_pkg_info( option[:pkg], option[:os] ) 
+when "list-rpkg" then
+    client = Client.new( option[:url], nil, nil )
+    if not option[:url].nil? then
+        client.update()
+    end
+       result = client.show_pkg_list( option[:os] )
+    if not result.nil? and not result.empty? then
+        result.each do |i|
+            name = i[0].strip
+            version = i[1].strip
+            desc = i[2].strip
+            puts name + "  (" + version + ")"
+        end
+    end
+when "show-lpkg" then
+    client = Client.new( nil, option[:loc], nil )
+    puts client.show_installed_pkg_info( option[:pkg] )
+when "list-lpkg" then
+    client = Client.new( nil, option[:loc], nil )
+       result = client.show_installed_pkg_list()
+    if not result.nil? and not result.empty? then
+        result.each do |i|
+            name = i[0].strip
+            version = i[1].strip
+            desc = i[2].strip
+            puts name + "  (" + version + ")"
+        end
+    end
+when "build-dep" then
+    client = Client.new( nil, nil, nil )
+       result = client.get_build_dependent_packages( option[:pkg], option[:os], true )
+    ret = ""
+    result.each do |i|
+        ret = ret + i + " --> "
+    end
+    ret = ret.strip
+    ret[-3..-1] = ""
+    puts ret
+when "install-dep" then
+    client = Client.new( nil, nil, nil )
+       result = client.get_install_dependent_packages( option[:pkg], option[:os], true, false )
+    ret = ""
+    result.each do |i|
+        ret = ret + i + " --> "
+    end
+    ret = ret.strip
+    ret[-3..-1] = ""
+    puts ret
+else
+       raise RuntimeError, "input option incorrect : #{option[:cmd]}"
+end
+
diff --git a/pkg-svr b/pkg-svr
new file mode 100755 (executable)
index 0000000..3cf4121
--- /dev/null
+++ b/pkg-svr
@@ -0,0 +1,101 @@
+#!/usr/bin/ruby 
+
+=begin
+ pkg-svr
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'fileutils'
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/pkg_server"
+require "utils"
+require "packageServer"
+require "serverOptParser"
+
+#option parsing 
+begin
+       option = option_parse
+rescue => e
+       puts "\n=============== Error occured =============================="
+       puts e.message
+       puts e.backtrace.inspect
+       puts "=============================================================\n"
+       exit 0
+end
+
+begin 
+       if option[:cmd].eql? "list" then
+               if option[:id].empty? then
+                       PackageServer.list_id 
+               else
+                       PackageServer.list_dist option[:id]
+               end 
+               exit 
+       end 
+
+       server = PackageServer.new( option[:id] )
+
+       if server.nil? 
+               raise RuntimeError, "server class creation fail"
+       end
+
+       case option[:cmd] 
+       when "create"  
+               server.create( option[:id], option[:dist], option[:url], option[:loc] )
+       when "register"
+               server.register( option[:spkgs], option[:bpkgs], option[:dist], option[:gensnap], option[:test] ) 
+       when "gen-snapshot"
+               server.generate_snapshot( option[:snap], option[:dist], option[:bsnap], option[:bpkgs] ) 
+       when "sync"
+               server.sync( option[:dist], option[:force] )
+       when "add-dist"
+               server.add_distribution( option[:dist], option[:url], option[:clone] )
+       when "spkg-path" 
+               server.find_source_package_path( option[:dist], option[:spkgs] )
+       when "remove"
+               puts  "Do you want to really? then input \"YES\""
+               input = $stdin.gets.strip
+               if input.eql? "YES" then   
+                       puts "Remove server!"
+               else
+                       puts "Remove is canceled by user input"
+                       exit(0)
+               end
+
+               server.remove_server( option[:id] )
+       when "remove-pkg"
+               server.remove_pkg( option[:id], option[:dist], option[:bpkgs] )
+       else
+               raise RuntimeError, "input option incorrect : #{option[:cmd]}"
+       end
+rescue => e 
+       puts "\n=============== Error occured =============================="
+       puts e.message
+       puts e.backtrace.inspect
+       puts "=============================================================\n"
+end
+
+
diff --git a/src/build_server/BuildClientOptionParser.rb b/src/build_server/BuildClientOptionParser.rb
new file mode 100644 (file)
index 0000000..79941ca
--- /dev/null
@@ -0,0 +1,97 @@
+=begin
+ BuildClientOptionParser.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'optparse'
+
+def option_parse 
+    options = {}
+    banner = "Usage: build-cli {build|resolve|query} ..." + "\n" \
+               + "\t" + "build-cli build -g <git-repository> -c <git-commit> [-d <svr domain>] [-p <svr-port>] [-o <os>] [-a <async>] " + "\n" \
+               + "\t" + "build-cli resolve -g <git-repository> -c <git-commit> [-d <svr domain>] [-p <svr-port>] [-o <os>] [-a <async>] " + "\n" \
+               + "\t" + "build-cli query [-d <svr domain>] [-p <svr-port>] [-o <os>] " + "\n" 
+
+    optparse = OptionParser.new do|opts|
+        # Set a banner, displayed at the top
+        # of the help screen.
+
+               opts.banner = banner 
+
+               opts.on( '-g', '--git <git-repository>', 'git repository' ) do|git|
+            options[:git] = git
+        end
+
+               opts.on( '-c', '--commit <git-commit>', 'git commit id/tag' ) do|git|
+            options[:commit] = git
+        end
+
+        options[:domain] = nil
+               opts.on( '-d', '--domain <build-svr-domain>', 'remote build server ip address. default 172.21.111.177' ) do|domain|
+            options[:domain] = domain
+        end
+               
+        options[:port] = nil
+               opts.on( '-p', '--port <build-svr-port>', 'remote build server port. default 2222' ) do|port|
+            options[:port] = port
+        end
+               
+        options[:os] = nil
+               opts.on( '-o', '--os <operating system>', 'target operating system linux/windows/darwin' ) do|os|
+            options[:os] = os
+        end
+
+        options[:async] = "NO"
+               opts.on( '-a', '--async', 'asynchronous job' ) do
+            options[:async] = "YES"
+        end
+       
+               opts.on( '-h', '--help', 'display this information' ) do
+            puts opts
+                       exit
+        end
+               
+    end
+    
+       cmd = ARGV[0] 
+
+    if cmd.eql? "build" or cmd.eql? "resolve" or cmd.eql? "query" or 
+                cmd =~ /(help)|(-h)|(--help)/ then
+
+        if cmd.eql? "help" then 
+                       ARGV[0] = "-h" 
+               end
+
+        options[:cmd] = ARGV[0]
+    else
+        raise ArgumentError, banner
+    end
+
+    optparse.parse!
+   
+    return options
+end 
+
diff --git a/src/build_server/BuildComm.rb b/src/build_server/BuildComm.rb
new file mode 100644 (file)
index 0000000..94f8bb1
--- /dev/null
@@ -0,0 +1,257 @@
+require "socket"
+
+=begin
+ BuildComm.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)+"/src/common"
+require "log"
+
+class BuildCommServer
+       VERSION = "1.2.0"
+
+       def initialize(port, log)
+               @port = port
+               @tcp_server = TCPServer.open( port )
+               @log = log
+       end
+
+
+       # wait for connection and handle request
+       def wait_for_connection(quit_loop)
+               while( not quit_loop )
+                       req = @tcp_server.accept                
+       
+                       begin
+                               yield req
+                       rescue
+                               @log.error "Caught a connection exception"
+                               req.close
+                       end
+               end
+       end
+
+
+       # terminate
+       def terminate
+               @tcp_server.close()
+       end
+
+       
+       # send_begin
+       def self.send_begin( req )
+               send( req, "=BEGIN,#{VERSION}")
+       end
+
+
+       def self.send_end( req )
+               send( req, "=END")
+       end
+
+
+       def self.send_chk( req )
+               send( req, "=CHK" )
+       end
+
+
+       def self.send( req, line )
+               begin
+                       if not req.nil? then
+                               req.puts line
+                       end
+               rescue
+                       raise "Connection is closed"
+               end
+       end
+
+
+       def self.disconnect( req )
+               begin
+                       req.close
+               rescue
+               end
+       end
+end
+
+
+class BuildCommClient
+       VERSION = "1.2.0"
+
+       private_class_method :new
+
+       def initialize(socket)
+               @socket = socket
+       end
+
+
+       # create
+       def self.create(ip, port)
+               # open socket
+               begin
+                       socket = TCPSocket.open( ip, port )
+               rescue
+                       # unknown exception
+                       return nil
+               end
+
+               # refused
+               if socket.nil? then
+                       return nil 
+               end 
+
+               return new(socket)
+       end
+
+
+       def send( msg )
+               if @socket.nil? then return false end
+
+               @socket.puts( msg )
+               return true
+       end     
+
+
+       def print_stream
+
+               begin
+                       l = @socket.gets()
+
+                       if @socket.nil? then 
+                               puts "Connection refused"
+                               return false 
+                       end
+
+                       # check protocol
+                       if not protocol_matched? l.strip then
+                               puts "Comm. Protocol version is mismatched! #{VERSION}"
+                               return false
+                       end
+
+               
+                       # get contents
+                       while line = @socket.gets()
+                               if line.strip == "=END" then break end
+                               if line.strip == "=CHK" then next end
+                               # print
+                               puts line.strip
+                       end
+               rescue
+                       puts "Connection closed"
+                       return false
+               end
+
+               return true
+       end
+
+
+       # handle 
+       def read_lines
+
+               begin
+                       # get first line
+                       l = @socket.gets()
+
+                       if @socket.nil? then 
+                               return false 
+                       end
+
+                       # check protocol
+                       if not protocol_matched? l.strip then
+                               return false
+                       end
+
+                       # get contents
+                       while line = @socket.gets()
+                               if line.strip == "=END" then break end
+                               if line.strip == "=CHK" then next end
+
+                               # print
+                               yield line.strip
+                       end
+               rescue
+                       return false
+               end
+
+               return true
+       end
+
+
+       # return result
+       def receive_data
+               result = []
+
+               begin
+                       l = @socket.gets()
+
+                       if @socket.nil? then 
+                               puts "Connection refused"
+                               return nil
+                       end
+
+                       # check protocol
+                       if not protocol_matched? l.strip then
+                               puts "Comm. Protocol version is mismatched! #{VERSION}"
+                               return nil
+                       end
+
+               
+                       # get contents
+                       while line = @socket.gets()
+                               if line.strip == "=END" then break end
+                               if line.strip == "=CHK" then next end
+                               # print
+                               result.push line.strip
+                       end
+               rescue
+                       puts "Connection closed"
+                       return nil
+               end
+
+               return result
+       end
+
+
+       def terminate
+               @socket.close
+       end
+
+       
+       private
+
+
+       # check protocol
+       def protocol_matched?(l)
+
+               version = ( l.split(",")[1].nil? ? "1.0.0" : l.split(",")[1] ) 
+               if not l.start_with? "=BEGIN" or
+                       version.nil? or version != VERSION then
+                       return false
+               else
+                       return true
+               end     
+       end
+end
diff --git a/src/build_server/BuildJob.rb b/src/build_server/BuildJob.rb
new file mode 100644 (file)
index 0000000..2a7f5c7
--- /dev/null
@@ -0,0 +1,413 @@
+=begin
+ BuildJob.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+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__))+"/builder"
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/pkg_server"
+require "client.rb"
+require "PackageManifest.rb"
+require "Version.rb"
+require "Builder.rb"
+require "BuildServer.rb"
+require "JobLog.rb"
+require "mail.rb"
+
+class BuildJob
+
+       attr_accessor :blocked_by
+
+       # initialize
+       def initialize ()
+               @blocked_by = []
+       end
+
+       # execute
+       def execute
+               @log.info( "Invoking a thread for building Job #{@id}", Log::LV_USER)
+               if @status == "ERROR" then return  end
+               @thread = Thread.new {
+                       # main
+                       thread_main()
+                       
+                       # close 
+                       terminate()
+               } 
+       end
+
+
+       # remote
+       def execute_remote(server)
+               @log.info( "Invoking a thread for remote-building Job #{@id}", Log::LV_USER)
+               if @status == "ERROR" then return  end
+               @thread = Thread.new {
+                       # main
+                       remote_thread_main( server )
+                       
+                       # close 
+                       terminate()
+               } 
+       end
+
+
+       # check building is possible
+       def can_be_built_on?(host_os)
+               for pkg in @pkginfo.packages
+                       if pkg.os == @os and pkg.build_host_os.include? host_os then
+                               return true
+                       end
+               end
+               
+               return false
+       end
+
+
+       def has_same_packages?( wjob )
+               for pkg in @pkginfo.packages
+                       for wpkg in wjob.pkginfo.packages
+                               if pkg.package_name == wpkg.package_name then
+                                       #puts "Removed from candiated... A == B"
+                                       return true
+                               end
+                       end
+               end
+               return false
+       end
+
+
+       def does_depend_on?( wjob )
+               for dep in @pkginfo.get_build_dependencies(@os, BuildServer::HOST_OS)
+                       for wpkg in wjob.pkginfo.packages
+                               if dep.package_name == wpkg.package_name then
+                                       #puts "Removed from candiated... A -> B"
+                                       return true
+                               end
+                       end
+               end
+               return false
+       end
+
+
+       def does_depended_by?( wjob )
+               for pkg in @pkginfo.packages
+                       for dep in wjob.pkginfo.get_build_dependencies(@os, BuildServer::HOST_OS)
+                               if pkg.package_name == dep.package_name then
+                                       #puts "Checking... A <- B"
+                                       return true
+                               end
+                       end
+               end
+               return false
+       end
+
+
+       def is_connected?
+
+               # nil? then false
+               if @outstream.nil? then
+                       return false
+               end
+
+               # send chk signal
+               begin
+                       BuildCommServer.send_chk( @outstream )
+               rescue
+                       return false
+               end
+
+               return true
+       end
+
+
+       # return the job is asyncronous job
+       def is_asynchronous_job?
+               if @outstream.nil? then
+                       return true
+               else
+                       return false
+               end
+       end
+       #
+       # PROTECTED METHODS
+       #
+       protected
+
+
+       # main module   
+       def thread_main
+               @log.info( "New Job #{@id} is started", Log::LV_USER)
+               
+               @status = "BUILDING"
+
+               # update local package server
+               @server.local_pkgsvr.sync( @server.local_pkgsvr.get_default_dist_name(), false )
+
+               # checking version
+               if not check_package_version()
+                       @status = "ERROR"
+
+                       return
+               end
+
+               # checking build dependency
+               if not check_build_dependency()
+                       @status = "ERROR"
+                       return
+               end
+
+               # clean build
+               if not build()
+                       @status = "ERROR"
+                       return
+               end
+
+               # upload
+               if not upload()
+                       @status = "ERROR"
+                       return
+               end
+               
+               # INFO. don't change this string
+               @log.info( "Job is completed!", Log::LV_USER)
+               @status = "FINISHED"
+       end
+
+
+       # check if local package version is greater than server
+       def     check_package_version()
+               @log.info( "Checking package version ...", Log::LV_USER)
+
+               # package update
+               @pkgsvr_client.update
+
+               for pkg in @pkginfo.packages
+                       ver_local = pkg.version
+                       #ver_svr = @pkgsvr_client.get_package_version( pkg.package_name, @os )
+            ver_svr = @pkgsvr_client.get_attr_from_pkg( pkg.package_name, @os, "version")
+                       if not ver_svr.nil? and Version.new(ver_local) <= Version.new(ver_svr) then
+                               @log.error( "Version must be increased : #{ver_local} <= #{ver_svr}", Log::LV_USER)
+                               return false
+                       end
+               end
+
+               return true
+       end
+
+
+       # build dependency version
+       def check_build_dependency()
+               @log.info( "Checking build dependency ...", Log::LV_USER)
+
+               for dep in @pkginfo.get_build_dependencies( @os, @host_os )
+                       #ver_svr = @pkgsvr_client.get_package_version( dep.package_name, @os )
+                       if dep.target_os_list.count != 0 then
+                               dep_target_os = dep.target_os_list[0]
+                       else
+                               dep_target_os = @os
+                       end
+                       ver_svr = @pkgsvr_client.get_attr_from_pkg( dep.package_name, dep_target_os, "version")
+
+                       if ver_svr.nil?
+                               @log.error( "The package \"#{dep.package_name}\" for build-dependency is not found}", Log::LV_USER)
+                               return false
+                       end
+
+                       if not dep.match? ver_svr
+                               @log.error( "Version for build-dependency in not matched : server version => #{ver_svr}", Log::LV_USER)
+                               return false
+                       end
+               end     
+               
+               return true
+       end
+
+
+       # build clean
+       def     build()
+        if @resolve then 
+                       @log.info( "Resolving job...", Log::LV_USER)
+               else
+                       @log.info( "Building job...", Log::LV_USER)
+               end 
+
+               # create builder 
+               builder = Builder.create( "JB#{@id}", @pkgserver_url,@log.path )
+               if builder.nil?
+                       @log.error( "Creating job builder failed", Log::LV_USER)
+                       return false
+               end
+               @log.info( "JobBuilder##{@id} is created", Log::LV_USER)
+               
+               # set log output
+               builder.log.close
+               builder.log = @log
+
+        #make pending_pkg_dir_list
+        pending_pkg_dir_list = []
+        ignore_rev_dep_build_list = []
+        @pkginfo.packages.each do |i|
+            @server.pending_jobs.each do |pj|
+                if pj.rev_fail_list.include? i.package_name then 
+                    pending_pkg_dir_list.push pj.source_path
+                    pending_pkg_dir_list += pj.rev_success_list.map {|pjs| pjs.source_path}
+                    ignore_rev_dep_build_list = pj.rev_fail_list
+                    break
+                end 
+            end 
+            if not pending_pkg_dir_list.empty? then break end 
+        end 
+        dependency_package_exist = (not pending_pkg_dir_list.empty?)
+
+               # build 
+        if @resolve then  
+            @rev_fail_list = builder.build_resolve(@source_path, @os, [], []) 
+
+            # clean build failed
+            if @rev_fail_list.nil? then 
+                @log.error( "Resolve building job failed", Log::LV_USER)
+                return false
+            end
+
+            # pending 
+            @status = "PENDING"
+
+            # rev build successed
+            if @rev_fail_list.empty? then 
+                @rev_success_list.each do |s|
+                    s.status = ""
+                end 
+                @status = ""
+            end
+
+            while @status == "PENDING" 
+                sleep 1
+            end 
+            return true
+        else
+            if not builder.build(@source_path, @os, true, true, pending_pkg_dir_list, ignore_rev_dep_build_list )
+                @log.error( "Building job failed", Log::LV_USER)
+                return false
+            end
+
+            if dependency_package_exist then 
+                @server.pending_jobs.each do |j| 
+                    if j.source_path == pending_pkg_dir_list[0] then 
+                        j.rev_fail_list -= @pkginfo.packages.map{|p| p.package_name}
+                        j.rev_success_list.push self
+                        if j.rev_fail_list.empty? then 
+                            j.rev_success_list.each do |s|
+                                s.status = ""
+                            end 
+                            j.status = ""
+                        else
+                            @status = "PENDING"
+                            while @status == "PENDING" 
+                                sleep 1
+                            end 
+                        end 
+                        break
+                    end 
+                end 
+            end 
+        end
+
+               # remove builder
+               Builder.remove( "builder_#{@id}" )
+               
+               return true
+       end
+
+
+       def upload()
+               @log.info( "Uploading ...", Log::LV_USER)
+       
+               # get package path list
+               binpkg_path_list = Dir.glob("#{@source_path}/*_*_#{@os}.zip")
+               srcpkg_path_list = Dir.glob("#{@source_path}/*.tar.gz")
+
+               # upload
+               u_client = Client.new( @server.pkgserver_url, nil, @log )
+               u_client.update
+               snapshot = u_client.upload( @server.pkgserver_addr, 
+                       @server.pkgserver_id, binpkg_path_list, srcpkg_path_list, true)
+
+               if snapshot.nil? then
+                       @log.info( "Upload failed...", Log::LV_USER)
+
+                       return false
+               end
+       
+               # update local
+               @log.info( "Upload succeeded. Sync local pkg-server again...", Log::LV_USER)
+               @pkgsvr_client.update
+               @server.local_pkgsvr.sync( @server.local_pkgsvr.get_default_dist_name(), false )
+               @log.info("Snapshot: #{snapshot}", Log::LV_USER)
+       
+               return true
+       end
+
+
+       # remote main module    
+       def remote_thread_main(server)
+               @log.info( "Job #{@id} is requested to be built on remote server ", Log::LV_USER)
+               
+               @status = "REMOTE_BUILDING"
+
+               # open
+               client = BuildCommClient.create( server.remote_ip, server.port )
+               if client.nil? then
+                       @status = "ERROR"
+                       return
+               end
+               
+               # send & receive
+               if client.send("BUILD,GIT,#{@git_repos},#{@git_commit},#{@os},,NO") then
+                       result = client.read_lines do |l|
+                               if l.include? "Job is stopped by ERROR" then
+                                       @status = "ERROR"
+                               end
+                               # ddd list
+                               @log.output( l.strip, Log::LV_USER)
+                       end
+                       if not result then @status = "ERROR" end
+               end
+
+               # close socket
+               client.terminate
+
+               # INFO. don't change this string
+               if @status != "ERROR" then
+                       @log.info( "Job is just finished", Log::LV_USER)
+                       @status = "FINISHED"
+               end
+
+               return  
+       end
+
+end
diff --git a/src/build_server/BuildServer.rb b/src/build_server/BuildServer.rb
new file mode 100644 (file)
index 0000000..7862f98
--- /dev/null
@@ -0,0 +1,496 @@
+=begin
+ BuildServer.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'fileutils'
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/pkg_server"
+require "SocketJobRequestListener.rb"
+require "RemoteBuildJob.rb"
+require "LocalBuildJob.rb"
+require "packageServer.rb"
+
+class BuildServer
+       attr_accessor :id, :path, :pkgserver_url, :pkgserver_addr, :pkgserver_id, :remote_ip, :port, :status, :friend_servers, :host_os, :log
+       attr_accessor :max_working_jobs, :working_jobs, :waiting_jobs, :remote_jobs, :pending_jobs
+       attr_accessor :git_server_url, :git_bin_path
+       attr_accessor :job_log_url
+       attr_accessor :job_index
+       attr_accessor :allowed_git_branch
+       attr_accessor :pkgsvr_cache_path, :local_pkgsvr
+
+       CONFIG_ROOT = "#{Utils::HOME}/.build_tools/build_server"
+       HOST_OS = Utils::HOST_OS
+
+       # initialize
+       def initialize (id, path, pkgserver_url, pkgserver_addr, pkgserver_id)
+               @id = id
+               @path = path
+               @pkgserver_url = pkgserver_url
+               @pkgserver_addr = pkgserver_addr
+               @pkgserver_id = pkgserver_id
+               @friend_servers = []
+               @waiting_jobs = []
+               @working_jobs = []
+               @pending_jobs = []
+               @remote_jobs = []
+               @max_working_jobs=2
+               @req_listener = []
+               @finish = false
+               # for friend server
+               @remote_ip = nil
+               # port number
+               @port = 2222
+               # status
+               @status = "RUNNING"
+               # host_os
+               @host_os = HOST_OS
+               # log
+               @log = nil
+               @git_server_url = "gerrithost"
+               @git_bin_path = "/usr/bin/git"
+               @job_index = 0
+               @job_log_url = ""
+               @allowed_git_branch = ""
+               # local package server
+               @pkgsvr_cache_path = nil
+               @local_pkgsvr = nil
+       end
+
+
+       # start server daemon
+       def start
+               # start logger
+               @log = Log.new( "#{BuildServer::CONFIG_ROOT}/#{@id}/log" )
+
+               # set local package server for cache
+               @log.info "Setting local package server..."
+               pkgsvr_id = @id
+               pkgsvr_dist = @pkgserver_url.split("/")[-1]
+               @local_pkgsvr = PackageServer.new( pkgsvr_id )
+               if @local_pkgsvr.location.empty? then 
+                       FileUtils.mkdir_p @pkgsvr_cache_path
+                       @local_pkgsvr.create(pkgsvr_id, pkgsvr_dist, @pkgserver_url, @pkgsvr_cache_path )
+               else
+                       # check path is changed, recreate it
+                       if @local_pkgsvr.location != "#{@pkgsvr_cache_path}/#{pkgsvr_id}" then
+                               # remove
+                               @local_pkgsvr.remove_server( pkgsvr_id )
+                               # create
+                               FileUtils.mkdir_p @pkgsvr_cache_path
+                               @local_pkgsvr.create(pkgsvr_id, pkgsvr_dist, @pkgserver_url, @pkgsvr_cache_path )
+                       end
+               end
+
+               # set job request listener
+               @log.info "Setting listener..."
+               listener2 = SocketJobRequestListener.new(self)
+               listener2.start
+               @req_listener.push listener2
+       
+               # main loop
+               @log.info "Entering main loop..."
+               while( not @finish )
+                       # handle jobs
+                       handle()
+                       sleep 1
+               end
+       end
+
+
+       # stop sever daemon
+       def stop
+               @finish = true
+       end
+
+
+       # add a normal job
+       def add_job ( new_job )
+               @log.info "Added new job \"#{new_job.id}\""
+
+               Thread.new {
+                       # pre-verifiy
+                       if not new_job.pre_verify or new_job.status == "ERROR" then
+                               new_job.status = "ERROR"
+                               @log.info "Adding the job \"#{new_job.id}\" is canceled"
+                               new_job.terminate()
+                               Thread.current.exit
+                       end
+
+                       # check availabiltiy
+                       if not check_job_availability( new_job ) then
+                               new_job.log.error( "No servers that are able to build your packages.", Log::LV_USER)
+                               new_job.status = "ERROR"
+                               @log.info "Adding the job \"#{new_job.id}\" is canceled"
+                               new_job.terminate()
+                               Thread.current.exit
+                       end
+
+                       @waiting_jobs.push( new_job )
+                       new_job.status = "WAITING"
+                       @log.info "Checking the job \"#{new_job.id}\" was finished!"
+               }
+       end
+
+
+       # get job list
+       def get_job_list()
+               list = []
+               list = list + @working_jobs + @remote_jobs + @waiting_jobs
+
+               return list
+       end
+
+
+       # query job status
+       def get_job_status( job )
+               return job.status
+       end
+
+
+       # check the job can be built on this server
+       def can_build?(job)
+
+               # check me
+               if job.can_be_built_on? @host_os then
+                       return true
+               end
+
+               return false
+       end
+
+
+       def get_new_job_id
+               # get new id
+               new_id = @job_index
+
+               # save it
+               server_dir = "#{BuildServer::CONFIG_ROOT}/#{@id}"
+               f = File.open( "#{server_dir}/latest_job", "w" )
+               f.puts "#{new_id}"
+               f.close
+
+               # increae job idex
+               @job_index = @job_index + 1
+
+               return new_id
+       end
+
+
+       # add new remote friend server
+       def add_friend_server( ip, port )
+       
+               # if already exit, return false
+               for svr in @friend_servers
+                       if svr.remote_ip.eql? ip and svr.port == port then
+                               return false
+                       end     
+               end
+
+               # create new one, and add it into list
+               new_server = BuildServer.new( "#{ip}_#{port}", nil, nil, nil, nil )
+               new_server.remote_ip = ip
+               new_server.port = port
+               new_server.status = "UNDEFINED"
+               @friend_servers.push new_server
+
+               return true
+       end
+
+
+       # query remote server info & update server state
+       def update_state
+
+               # only friend server
+               if not @path.nil? then return end
+
+               # send 
+               @status = "DISCONNECTED"
+               client = BuildCommClient.create( @remote_ip, @port )
+               if client.nil? then return end
+               if client.send("QUERY,SYSTEM") then
+                       result = client.read_lines do |l|
+                               tok = l.split(",").map { |x| x.strip }
+                               @host_os = tok[0]
+                               @max_working_jobs = tok[1].to_i
+                               @status = "RUNNING"
+                       end
+                       if not result then @status = "DISCONNECTED" end
+               end
+               client.terminate
+               if @status == "DISCONNECTED" then return end
+
+               # send  
+               @working_jobs = []
+               @waiting_jobs = []
+               client = BuildCommClient.create( @remote_ip, @port )
+               if client.nil? then return end
+               if client.send("QUERY,JOB") then
+                       result = client.read_lines do |l|
+                               tok = l.split(",").map { |x| x.strip }
+                               
+                               job_status = tok[0]
+                               job_id = tok[1]
+                               new_job = RemoteBuildJob.new(job_id)
+                               case job_status
+                               when "WAITING" 
+                                       @waiting_jobs.push new_job
+                               when "WORKING" 
+                                       @working_jobs.push new_job
+                               else
+                                       #puts "Uncontrolled status"
+                               end     
+                       end
+                       if not result then @status = "DISCONNECTED" end
+               else
+                       @status = "DISCONNECTED"
+               end
+               client.terminate
+       end
+
+
+       private
+
+       def handle()
+               # update friend server status
+               for server in @friend_servers
+                       # update state
+                       server.update_state
+               end
+
+               # Move working -> finished
+               #) Move working -> pending
+               for job in @working_jobs
+                       if job.status == "ERROR"
+                               @log.info "Job \"#{job.id}\" is stopped by ERROR" 
+                               @working_jobs.delete job        
+                       elsif job.status == "FINISHED" 
+                               @working_jobs.delete job
+                       elsif job.status == "PENDING" 
+                               @working_jobs.delete job
+                               @pending_jobs.push job
+                       end
+               end
+
+               # Move pending -> finished 
+               for job in @pending_jobs
+                       if job.status == "ERROR"
+                               @log.info "Job \"#{job.id}\" is stopped by ERROR" 
+                               @pending_jobs.delete job        
+                       elsif job.status == "FINISHED" 
+                               @pending_jobs.delete job
+                       end
+               end
+
+               # Move remote -> finished 
+               for job in @remote_jobs
+                       if job.status == "ERROR"
+                               @log.info "Job \"#{job.id}\" is stopped by ERROR" 
+                               @remote_jobs.delete job 
+                       elsif job.status == "FINISHED" 
+                               @remote_jobs.delete job
+                       end
+               end
+
+               # MOVE waiting -> finished
+               for job in @waiting_jobs
+                       if job.status == "ERROR"  then
+                               @waiting_jobs.delete( job )
+                               @log.info "Job \"#{job.id}\" is removed by internal error"
+                       end
+               end
+
+               # MOVE waiting -> working
+               if @waiting_jobs.count > 0 then
+                       
+                       # get available job
+                       job = get_available_job
+
+                       # available job not exist?, continue
+                       if ( job.nil? ) then return end
+
+                       # oherwise, check remote server
+                       rserver = get_available_server( job )
+
+                       # request for build
+                       if rserver != nil and rserver == self then
+
+                               # change 
+                               @waiting_jobs.delete job
+                               @working_jobs.push job
+
+                               # start build
+                               job.execute
+                               @log.info "Moved the job \"#{job.id}\" to working job list" 
+
+                       elsif rserver != nil  then
+                               if job.execute_remote( rserver ) then
+
+                                       # status change & job control
+                                       job.status = "REMOTE_WAITING"
+                                       @waiting_jobs.delete( job )
+                                       @remote_jobs.push( job )
+                                       @log.info "Moved the job \"#{job.id}\" to remote job list" 
+                               else
+                                       @log.info "Moving the job \"#{job.id}\" to remote failed" 
+                               end
+                       else
+                               #puts "No available server"
+                       end
+               end
+
+               #check the connection if the waiting job is not asynchronous job
+               for job in @waiting_jobs
+                       if not job.is_asynchronous_job? and not job.is_connected? then
+                               @waiting_jobs.delete( job )
+                               @log.info "Job \"#{job.id}\" is disconneted by user. Removed!"
+                       end
+               end
+               for job in @remote_jobs
+                       if not job.is_asynchronous_job? and not job.is_connected? then
+                               @remote_jobs.delete( job )
+                               @log.info "Job \"#{job.id}\" is disconneted by user. Removed!"
+                       end
+               end
+               
+       end
+
+
+       # select the job whith no build-dependency problem 
+       def get_available_job
+       
+               # gather all working jobs
+               all_working_jobs = [] + @working_jobs
+               all_working_jobs = all_working_jobs + @remote_jobs
+       
+               # for waiting jobs      
+               for job in @waiting_jobs
+                       blocked_by = []
+                       is_changed = false
+               
+                       # should not have same packages with workings
+                       # should not depend on workings
+                       # should not be depended by workings
+                       for wjob in all_working_jobs
+                               if job.has_same_packages?( wjob ) or
+                                       job.does_depend_on?( wjob ) or
+                                       job.does_depended_by?( wjob ) then
+       
+                                       blocked_by.push wjob
+                                       # if there are some changes, check it
+                                       if not job.blocked_by.include? wjob then is_changed = true end
+                               end
+                       end
+                               
+                       # if available , then FIFO      
+                       if blocked_by.empty? then
+                               job.blocked_by = []
+                               return job
+                       else
+                               # check count
+                               if blocked_by.count != job.blocked_by.count then is_changed = true end
+
+                               # if somthing changed, print it and save it
+                               if is_changed then
+                                       job.log.info( "Waiting for finishing following jobs:", Log::LV_USER)
+                                       for bjob in blocked_by  
+                                               job.log.info( " * #{wjob.id} #{wjob.pkginfo.packages[0].source}", Log::LV_USER)
+                                       end
+                                       job.blocked_by = blocked_by
+                               end
+                       end
+               end
+               
+               return nil      
+       end
+
+
+       # get remote server     
+       def get_available_server ( job )
+               candidates = []
+               
+               # check local
+               if @working_jobs.count < @max_working_jobs and can_build?(job) then
+                       candidates.push self
+               end
+
+               # if Local build job, just check local
+               if job.instance_of? LocalBuildJob then return candidates[0] end
+
+               # get availables
+               for server in @friend_servers
+                       # select only "RUNNING" & possible one
+                       if ( server.status == "RUNNING" and server.can_build?( job ) and
+                               server.waiting_jobs.count == 0 and 
+                               server.working_jobs.count < server.max_working_jobs )
+                               candidates.push server
+                       end
+               end
+
+               best_server = candidates[0]
+               if best_server.nil? or candidates.count == 1 then return best_server end
+
+               # get best 
+               # it is better if working jobs count is less
+               max_empty_room = best_server.max_working_jobs - best_server.working_jobs.count
+               for server in candidates
+                       # check whether idle, use it 
+                       if server.working_jobs.count == 0 then return server end
+
+                       # skip
+                       if server == best_server then next end
+               
+                       # compare remain rooms
+                       empty_room = server.max_working_jobs - server.working_jobs.count
+                       if empty_room > max_empty_room then
+                               max_empty_room = empty_root
+                               best_server = server
+                       end
+               end
+                
+               return best_server
+       end
+
+
+       # check there is some servers that can build  the job
+       def check_job_availability(job)
+
+               # check me
+               if can_build? job then return true end
+
+               #if not found, check friends
+               for server in @friend_servers
+                       if server.status == "RUNNING" and 
+                               job.can_be_built_on? server.host_os then
+                               return true
+                       end
+               end
+
+               return false
+       end
+end
+
diff --git a/src/build_server/BuildServerController.rb b/src/build_server/BuildServerController.rb
new file mode 100644 (file)
index 0000000..b0b237b
--- /dev/null
@@ -0,0 +1,377 @@
+=begin
+ BuildServerController.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+require "BuildServer.rb"
+require "BuildComm.rb"
+
+class BuildServerController
+       @@instance_map = {}
+
+       # create
+       def self.create_server (id, path, pkgsvr_url, pkgsvr_addr, pkgsvr_id)
+
+               # check server config root
+               check_build_server_root
+
+               # check id
+               if File.exist? "#{BuildServer::CONFIG_ROOT}/#{id}"
+                       raise RuntimeError, "Creating server failed. The server id is already exist"
+               end
+
+               # create new instance and return it
+               @@instance_map[id] = BuildServer.new( id, path, pkgsvr_url, pkgsvr_addr, pkgsvr_id )
+               
+               # set default
+               @@instance_map[id].git_server_url="gerrithost:"
+               if Utils::HOST_OS == "windows" then
+                       @@instance_map[id].git_bin_path="/c/Program\\ Files/Git/bin/git.exe"
+               else
+                       @@instance_map[id].git_bin_path="/usr/bin/git"
+               end
+               @@instance_map[id].allowed_git_branch=nil
+               @@instance_map[id].max_working_jobs= 2
+               @@instance_map[id].job_log_url=""
+               @@instance_map[id].pkgsvr_cache_path="#{path}/pkgsvr_cache"
+       
+
+               # write config
+               write_server_config( @@instance_map[id] )
+
+               puts "Created new build server: \"#{id}\""
+               return @@instance_map[id]
+       end
+
+
+       def self.remove_server (id)
+
+               # check server config root
+               check_build_server_root
+
+               # check id
+               if File.exist? "#{BuildServer::CONFIG_ROOT}/#{id}"
+                       FileUtils.rm_rf "#{BuildServer::CONFIG_ROOT}/#{id}"
+                       @@instance_map[id] = nil
+                       puts "Removed the server \"#{id}\""
+               end
+               
+               # remove local package server
+               local_pkgsvr = PackageServer.new( id )
+               local_pkgsvr.remove_server(id)  
+
+       end
+
+
+       # get
+       def self.get_server( id )
+
+               # check instance first
+               if not @@instance_map[id] == nil
+                       return @@instance_map[id] 
+               end
+
+               # check server config 
+               if not File.exist? "#{BuildServer::CONFIG_ROOT}/#{id}/server.cfg" 
+                       raise RuntimeError, "The server \"#{id}\" does not exist."
+               end
+
+               # get server config and return its object
+               @@instance_map[id] = read_server_config(id)
+
+               return @@instance_map[id]
+       end
+
+
+       # start server
+       def self.start_server( id, port = 2222 )
+               server = get_server(id)
+       
+               # write run port        
+               server_dir = "#{BuildServer::CONFIG_ROOT}/#{server.id}"
+               f = File.open( "#{server_dir}/run", "w" )
+               f.puts port
+               f.close 
+
+               # write run job 
+               if File.exist? "#{server_dir}/latest_job" then
+                       f = File.open( "#{server_dir}/latest_job", "r" )
+                       server.job_index = f.gets.strip.to_i + 1
+                       f.close 
+               else
+                       f = File.open( "#{server_dir}/latest_job", "w" )
+                       f.puts "0"
+                       server.job_index = 0
+                       f.close
+               end     
+
+               # start
+               server.port = port
+               server.start
+       end
+
+
+       # stop server
+       def self.stop_server( id )
+               server = get_server(id)
+
+               # if the server is not running => error
+
+               # request stop
+       end
+
+
+       # add friend server
+       def self.add_friend_server( id, ip, port )
+               server = get_server(id)
+               
+               # add
+               if server.add_friend_server( ip, port ) then
+
+                       # write config  
+                       server_dir = "#{BuildServer::CONFIG_ROOT}/#{server.id}"
+                       f = File.open( "#{server_dir}/friends", "a" )
+                       f.puts "#{ip},#{port}"
+                       f.close 
+                       
+                       puts "Friend server is added successfully!"
+                       
+                       return true
+               else
+                       puts "Friend server already exists in list!"
+                       return false
+               end
+       end
+
+
+       # build git repository and upload
+       def self.build_git( id, repository, commit, os, url, resolve )
+
+               # server
+               server = get_server(id)
+               client = BuildCommClient.create( "127.0.0.1", server.port )
+               if client.nil? then return false end
+
+               # send request
+               client.send "BUILD,GIT,#{repository},#{commit},#{os}"
+
+               # recevie & print
+               client.print_stream
+
+               # terminate     
+               client.terminate
+
+               return true
+       end
+
+
+       # resolve git and build it and upload 
+       def resolve_git( id, repository, commit, os, url )
+               # server
+               server = get_server(id)
+               client = BuildCommClient.create( "127.0.0.1", server.port )
+               if client.nil? then return false end
+
+               # send request
+               client.send "RESOLVE,GIT,#{repository},#{commit},#{os}" 
+
+               # recevie & print
+               client.print_stream
+
+               # terminate     
+               client.terminate
+
+               return true
+       end
+
+
+       # build local project and upload
+       def self.build_local( id, local_path, os, url, resolve )
+               # server
+               server = get_server(id)
+               client = BuildCommClient.create( "127.0.0.1", server.port )
+               if client.nil? then return false end
+
+               # send request
+               client.send "BUILD,LOCAL,#{local_path},#{os}"
+
+               # recevie & print
+               client.print_stream
+
+               # terminate     
+               client.terminate
+
+               return true
+       end
+
+
+       # resolve local project and  build it and upload
+       def resolve_local( path, os )
+               # server
+               server = get_server(id)
+               client = BuildCommClient.create( "127.0.0.1", server.port )
+               if client.nil? then return false end
+
+               # send request
+               client.send "RESOLVE,LOCAL,#{local_path},#{os}"
+
+               # recevie & print
+               client.print_stream
+
+               # terminate     
+               client.terminate
+
+               return true
+       end
+
+       private
+
+       # check build server config path
+       def self.check_build_server_root
+               if not File.exist? BuildServer::CONFIG_ROOT
+                       puts "Server configuation is not found."
+                       puts "Creating new server configuration... #{BuildServer::CONFIG_ROOT}"
+                       FileUtils.mkdir_p "#{BuildServer::CONFIG_ROOT}"
+               end
+       end
+
+
+       # write server configuration
+       def self.write_server_config( server )
+               # create config folder
+               server_dir = "#{BuildServer::CONFIG_ROOT}/#{server.id}"
+               FileUtils.mkdir_p( "#{server_dir}" )
+
+               # write configuration
+               File.open( "#{server_dir}/server.cfg", "w" ) do |f|
+                       f.puts "ID=#{server.id}"
+                       f.puts "PATH=#{server.path}"
+                       f.puts "PSERVER_URL=#{server.pkgserver_url}"
+                       f.puts "PSERVER_ADDR=#{server.pkgserver_addr}"
+                       f.puts "PSERVER_ID=#{server.pkgserver_id}"
+                       f.puts "PSERVER_CACHE_PATH=#{server.pkgsvr_cache_path}"
+                       f.puts "GIT_SERVER_URL=#{server.git_server_url}"
+                       f.puts "GIT_BIN_PATH=#{server.git_bin_path}"
+                       f.puts "ALLOWED_GIT_BRANCH=#{server.allowed_git_branch}"
+                       f.puts "MAX_WORKING_JOBS=#{server.max_working_jobs}"
+                       f.puts "JOB_LOG_URL=#{server.job_log_url}"
+               end
+       end
+
+
+       # read server configuration
+       def self.read_server_config( id )
+               path=""
+               pkgsvr_url=""
+               pkgsvr_addr=""
+               pkgsvr_id=""
+               pkgsvr_cache_path=""
+               git_server_url="gerrithost:"
+               git_bin_path="/usr/bin/git"
+               allowed_git_branch=""
+               max_working_jobs= 2
+               job_log_url=""
+
+               # read configuration
+               server_dir = "#{BuildServer::CONFIG_ROOT}/#{id}"
+               File.open( "#{server_dir}/server.cfg", "r" ) do |f|
+                       f.each_line do |l|
+                               if l.start_with?("PATH=")
+                                       path = l.split("=")[1].strip
+                               elsif l.start_with?("PSERVER_URL=")
+                                       pkgsvr_url = l.split("=")[1].strip
+                               elsif l.start_with?("PSERVER_ADDR=")
+                                       pkgsvr_addr = l.split("=")[1].strip
+                               elsif l.start_with?("PSERVER_ID=")
+                                       pkgsvr_id = l.split("=")[1].strip
+                               elsif l.start_with?("PSERVER_CACHE_PATH=")
+                                       pkgsvr_cache_path = l.split("=")[1].strip
+                               elsif l.start_with?("GIT_SERVER_URL=")
+                                       git_server_url = l.split("=")[1].strip
+                               elsif l.start_with?("GIT_BIN_PATH=")
+                                       git_bin_path = l.split("=")[1].strip
+                               elsif l.start_with?("ALLOWED_GIT_BRANCH=")
+                                       allowed_git_branch = l.split("=")[1].strip
+                               elsif l.start_with?("MAX_WORKING_JOBS=")
+                                       max_working_jobs = l.split("=")[1].strip.to_i
+                               elsif l.start_with?("JOB_LOG_URL=")
+                                       job_log_url = l.split("=")[1].strip
+                               else
+                                       next    
+                               end 
+                       end
+               end
+
+               # create server object
+               obj = BuildServer.new( id, path, pkgsvr_url, pkgsvr_addr, pkgsvr_id )
+
+               # check running port
+               if File.exist? "#{server_dir}/run" then
+                       f = File.open( "#{server_dir}/run", "r" )
+                       l = f.gets
+                       obj.port = l.strip.to_i
+                       f.close
+               end
+
+               # check friend server
+               if File.exist? "#{server_dir}/friends" then
+                       File.open( "#{server_dir}/friends", "r" ) do |f|
+                               f.each_line do |l|
+                                       if l.split(",").count < 2 then next end
+                                       ip = l.split(",")[0].strip
+                                       port = l.split(",")[1].strip
+                                       obj.add_friend_server( ip, port.to_i )
+                               end
+                       end
+               end             
+
+               # set git server url
+               obj.git_server_url = git_server_url
+
+               # set git binary path
+               obj.git_bin_path = git_bin_path
+       
+               # set git binary path
+               obj.max_working_jobs = max_working_jobs
+
+               # set job log url
+               obj.job_log_url = job_log_url
+
+               # set allowed git branch name
+               obj.allowed_git_branch = allowed_git_branch
+
+               # set package server path
+               pkgsvr_cache_path = (pkgsvr_cache_path.empty? ? "#{path}/pkgsvr_cache":pkgsvr_cache_path)
+               obj.pkgsvr_cache_path= pkgsvr_cache_path
+
+               # save config
+               write_server_config( obj )
+               
+               # create object & return it
+               return obj
+       end
+end
diff --git a/src/build_server/BuildServerOptionParser.rb b/src/build_server/BuildServerOptionParser.rb
new file mode 100644 (file)
index 0000000..55fc370
--- /dev/null
@@ -0,0 +1,117 @@
+=begin
+ BuildServerOptionParser.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'optparse'
+
+def option_parse 
+    options = {}
+    banner = "Usage: build-svr {create|remove|start|build|help} ..." + "\n" \
+        + "\t" + "build-svr create -n <name> -u <pkg-server-url> -d <pkg-server-domain> -i <pkg-server-id>" + "\n" \
+        + "\t" + "build-svr remove -n <name>" + "\n" \
+        + "\t" + "build-svr start -n <name> [-p <port]" + "\n" \
+        + "\t" + "build-svr build -n <name> [-l <local-path>] [-g <git-repository> -c <git-commit>] [-o <os>] [-r]" + "\n"  \
+        + "\t" + "build-svr add -n <name> [-d <frined-svr-domain> -p <friend-svr port>]" + "\n" 
+
+    optparse = OptionParser.new do|opts|
+        # Set a banner, displayed at the top
+        # of the help screen.
+
+               opts.banner = banner 
+
+        opts.on( '-n', '--name <name>', 'build server name' ) do|name|
+            options[:name] = name 
+        end
+        
+               opts.on( '-u', '--url <pkg-server-url>', 'package server URL: http://xxx/yyy/zzz' ) do|url|
+            options[:url] = url 
+        end
+
+               opts.on( '-d', '--domain <pkg/friend-svr domain>', 'package svr or friend svr ip or ssh alias' ) do|domain|
+            options[:domain] = domain
+        end
+               
+               opts.on( '-i', '--id <pkg-server-id>', 'package server id' ) do|pid|
+            options[:pid] = pid
+        end
+
+        options[:port] = 2222
+               opts.on( '-p', '--port <port>', 'port' ) do|port|
+            options[:port] = port.strip.to_i
+        end
+               
+               opts.on( '-l', '--local <local-path>', 'local source path' ) do|path|
+            options[:local] = path
+        end
+               
+               opts.on( '-g', '--git <git-repository>', 'git repository gerrithost:/xxx/yyy/zzz' ) do|git|
+            options[:git] = git
+        end
+
+               opts.on( '-c', '--commit <git-commit>', 'git commit id/tag' ) do|git|
+               if git.start_with? "/" then
+                       git = git[1..-1]
+               end
+            options[:commit] = git
+        end
+
+               opts.on( '-o', '--os <operating system>', 'target operating system linux/windows/darwin' ) do|os|
+            options[:os] = os
+        end
+               
+        options[:resolve] = false
+               opts.on( '-r', '--resolve', 'reverse build dependency fail resolve' ) do
+            options[:resolve] = true
+        end
+
+               opts.on( '-h', '--help', 'display this information' ) do
+            puts opts
+                       exit
+        end
+               
+    end
+    
+       cmd = ARGV[0] 
+
+    if cmd.eql? "create" or cmd.eql? "remove" or cmd.eql? "start" or 
+               cmd.eql? "build" or cmd.eql? "add" or
+                cmd =~ /(help)|(-h)|(--help)/ then
+
+        if cmd.eql? "help" then 
+                       ARGV[0] = "-h" 
+               end
+
+        options[:cmd] = ARGV[0]
+    else
+        raise ArgumentError, banner
+    end
+
+    optparse.parse!
+   
+    return options
+end 
+
diff --git a/src/build_server/GitBuildJob.rb b/src/build_server/GitBuildJob.rb
new file mode 100644 (file)
index 0000000..d328925
--- /dev/null
@@ -0,0 +1,220 @@
+=begin
+ GitBuildJob.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require "fileutils"
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "BuildJob.rb"
+require "utils.rb"
+
+class GitBuildJob < BuildJob
+       attr_accessor :id, :status, :pkginfo, :pkgsvr_client, :thread, :log, :rev_fail_list, :rev_success_list, :source_path
+
+       # initialize
+       def initialize ( repos, commit, os, pkgsvr_url, options, server, parent, outstream, resolve)
+               super()
+        @rev_fail_list = []
+        @rev_success_list = []
+               @id = server.get_new_job_id()
+               @server = server
+               @parent = parent
+               @git_repos = repos
+               @git_commit = commit
+               @os = os
+               @host_os = Utils::HOST_OS
+               if not pkgsvr_url.nil? and not pkgsvr_url.empty? then
+                       @pkgserver_url = pkgsvr_url
+               else 
+                       local_pkgsvr = @server.local_pkgsvr
+                       @pkgserver_url = local_pkgsvr.location + "/" + local_pkgsvr.get_default_dist_name
+               end
+               @options = options
+        @resolve = resolve
+               @outstream = outstream
+
+               @status = "JUST_CREATED"
+               @sub_jobs = []
+               @job_root = "#{@server.path}/jobs/#{@id}"
+               @source_path = @job_root+"/temp"
+               @pkginfo = nil
+               @job_working_dir=@job_root+"/works"     
+
+               @thread = nil
+
+               # mkdir 
+               FileUtils.rm_rf "#{@server.path}/jobs/#{@id}"
+               FileUtils.mkdir_p "#{@server.path}/jobs/#{@id}"
+
+               # create logger
+               @log = JobLog.new(self,"#{@server.path}/jobs/#{@id}/log", outstream )
+       end
+
+
+       def terminate()
+
+               # report error
+               if @status == "ERROR" then
+                       @log.error( "Job is stopped by ERROR" , Log::LV_USER)
+               else
+                       # if succeeded, clean up
+                       FileUtils.rm_rf "#{@source_path}"
+                       FileUtils.rm_rf "#{@job_working_dir}"
+               end
+
+               # send mail 
+               if ( not @pkginfo.nil? ) and not ( @pkginfo.packages.nil? ) then 
+                       mail_list = []
+                       contents = []
+                       done_pkg_list = []
+                       contents.push " "
+                       contents.push " Git information : #{@git_commit} "
+                       contents.push " "
+                       contents.push "%-30s| %10s | %10s" % ["package name", "version", "os"]
+                       contents.push "---------------------------------------------------------------"
+                       for pkg in @pkginfo.packages  
+                               if not pkg.os.eql? @os then next end 
+                               mail_list = mail_list | Mail.parse_email( pkg.maintainer )  
+                               contents.push("%-30s| %10s | %10s" % [ pkg.package_name, pkg.version, pkg.os] )
+                       end
+                       
+                       if @status == "ERROR" then 
+                               subject = "[DIBS] Build fail" 
+                               contents.push " "
+                               contents.push "check log file"
+                               contents.push "* Log : #{@server.job_log_url}/#{@id}/log"
+                       else
+                               subject = "[DIBS] Build success" 
+                       end
+                       #Mail.send_mail(mail_list, subject, contents.join("\n"))
+               end 
+
+               # close logger
+               @log.close
+
+               # send END signal , if connectionn is valid 
+               if @status != "ERROR" and not @outstream.nil? then
+                       BuildCommServer.send_end(@outstream)
+               end
+
+               # close outstream
+               if not @outstream.nil? then
+                       BuildCommServer.disconnect( @outstream )
+               end
+       end
+
+
+       # verify
+       def pre_verify
+               @log.info( "Verifying job input...", Log::LV_USER)
+
+               # git clone
+               if not git_cmd("clone #{@server.git_server_url}#{@git_repos} temp", @job_root) then
+                       @log.error( "Failed on \"git clone #{@server.git_server_url}/#{@git_repos}\"", Log::LV_USER)
+                       @status = "ERROR"
+                       return false
+               end
+
+               # git reset
+               if not git_cmd("reset --hard #{@git_commit}", @source_path) then
+                       @log.error( "Failed on \"git reset --hard #{@git_commit}\"", Log::LV_USER)
+                       @status = "ERROR"
+                       return false
+               end
+
+               # check branch name if ALLOWED_GIT_BRANCH is not empty
+               if not @server.allowed_git_branch.empty? then
+                       is_correct_branch = false
+
+                       # origin/{branch_name}
+                       if @git_commit == "origin/#{@server.allowed_git_branch}" then
+                               is_correct_branch = true
+                       else    
+                               # get commit id
+                               commit_id = ""
+                               result_line = git_cmd_return("log -1",@source_path)
+                               if result_line != nil then
+                                       result_line.each do |l|
+                                               if l.start_with?("commit ") then
+                                                       commit_id = l.split(" ")[1].strip       
+                                               end
+                                       end
+                               end
+       
+                               # check branch
+                               if not commit_id.empty? and commit_id.length == 40 then
+                                       result_line = git_cmd_return("branch --contains=#{commit_id} -r", @source_path)
+                                       result_line.each do |l|
+                                               if l.include? "origin/#{@server.allowed_git_branch}" then
+                                                       is_correct_branch = true
+                                               end
+                                       end
+                               end
+                       end
+
+                       if not is_correct_branch then
+                               @log.error( "Wrong branch is used! Check your commit-id again", Log::LV_USER)
+                               @status = "ERROR"
+                               return false
+                       end
+               end
+               
+
+               # check pkginfo.manifest
+               if not File.exist? "#{@source_path}/package/pkginfo.manifest"
+                       @log.error( "package/pkginfo.manifest doest not exist", Log::LV_USER)
+                       @status = "ERROR"
+                       return false
+               end
+
+               # set up pkg info
+               @pkginfo = PackageManifest.new("#{@source_path}/package/pkginfo.manifest")
+
+               # set up pkgsvr_client
+               @pkgsvr_client =  Client.new(@pkgserver_url, @job_working_dir, @log)
+               @pkgsvr_client.update
+
+               return true
+       end
+
+
+    def git_cmd(cmd, working_dir)
+        build_command = "cd \"#{working_dir}\";#{@server.git_bin_path} #{cmd}"
+               ret = Utils.execute_shell_with_log(build_command,@log)
+               
+               return ret
+       end
+
+
+    def git_cmd_return(cmd, working_dir)
+        build_command = "cd \"#{working_dir}\";#{@server.git_bin_path} #{cmd}"
+               ret = Utils.execute_shell_return(build_command)
+               
+               return ret
+       end
+
+end
diff --git a/src/build_server/JobLog.rb b/src/build_server/JobLog.rb
new file mode 100644 (file)
index 0000000..c46db48
--- /dev/null
@@ -0,0 +1,70 @@
+=begin
+ JobLog.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__)) + "/common"
+require "log"
+require "logger"
+require "BuildComm.rb"
+
+class JobLog < Log
+
+       def initialize(job, path, stream_out)
+               super(path)
+               @parent_job=job
+               @second_out = stream_out
+       end
+
+
+       protected
+
+       # overide
+       def output_extra(msg)
+               begin 
+                       if not @second_out.nil? then
+                               BuildCommServer.send( @second_out, msg )
+                       end
+               rescue
+                       @parent_job.status="ERROR"
+                       close()
+                       error "Connection closed by remote client"
+
+                       # terminate job
+                       @parent_job.terminate
+
+                       # exit thread if independent worker thread
+                       if @parent_job.thread == Thread.current then
+                               error "Thread wiil be terminated"
+                               @parent_job.thread=nil
+                               Thread.exit
+                       end
+               end
+       end     
+
+
+end
diff --git a/src/build_server/LocalBuildJob.rb b/src/build_server/LocalBuildJob.rb
new file mode 100644 (file)
index 0000000..008ece6
--- /dev/null
@@ -0,0 +1,148 @@
+=begin
+ LocalBuildJob.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "BuildJob.rb"
+require "utils.rb"
+
+class LocalBuildJob < BuildJob
+       attr_accessor :id, :status, :pkginfo, :pkgsvr_client, :thread, :log, :rev_fail_list, :rev_success_list, :source_path
+
+       # initialize
+       def initialize (local_path, os, pkgserver_url, options, server, parent, outstream, resolve )
+               super()
+        @rev_fail_list = []
+        @rev_success_list = []
+               @id = server.get_new_job_id()
+               @server = server
+               @parent = parent
+               @local_path = local_path
+               @os = os
+               @host_os = Utils::HOST_OS
+               if not pkgserver_url.nil? then
+                       @pkgserver_url = pkgsvr_url
+               else 
+                       local_pkgsvr = @server.local_pkgsvr
+                       @pkgserver_url = local_pkgsvr.location + "/" + local_pkgsvr.get_default_dist_name
+               end
+               @options = options
+        @resolve = resolve
+               @outstream = outstream
+
+               @status = "JUST_CREATED"
+               @sub_jobs = []
+               @job_root = "#{@server.path}/jobs/#{@id}"
+        @source_path = @local_path
+        @pkginfo = nil
+        @pkgsvr_client = nil
+        @job_working_dir=@job_root+"/works"    
+
+        @thread = nil
+
+               # mkdir
+               FileUtils.rm_rf "#{@server.path}/jobs/#{@id}"
+               FileUtils.mkdir_p "#{@server.path}/jobs/#{@id}"
+
+               # create logger
+               @log = JobLog.new( self, "#{@server.path}/jobs/#{@id}/log", outstream )
+       end
+
+
+       def terminate()
+
+               # report error
+               if @status == "ERROR" then
+                       @log.error( "Job is stopped by ERROR", Log::LV_USER)
+               else
+                       # if succeeded, clean up
+                       FileUtils.rm_rf "#{@job_working_dir}"
+               end
+
+               # send mail 
+               if ( not @pkginfo.nil? ) and not ( @pkginfo.packages.nil? ) then 
+                       mail_list = []
+                       contents = []
+                       done_pkg_list = []
+                       contents.push " "
+                       contents.push "%-30s| %10s | %10s" % ["package name", "version", "os"]
+                       contents.push "---------------------------------------------------------------"
+                       for pkg in @pkginfo.packages  
+                               if not pkg.os.eql? @os then next end 
+                               mail_list = mail_list | Mail.parse_email( pkg.maintainer )  
+                               contents.push("%-30s| %10s | %10s" % [ pkg.package_name, pkg.version, pkg.os] )
+                       end
+                       
+                       if @status == "ERROR" then 
+                               subject = "[DIBS] Build fail" 
+                               contents.push " "
+                               contents.push "check log file"
+                               contents.push "* Log : #{@server.job_log_url}/#{@id}/log"
+                       else
+                               subject = "[DIBS] Build success" 
+                       end
+                       #Mail.send_mail(mail_list, subject, contents.join("\n")) 
+               end
+                       
+               # close logger
+               @log.close
+
+               # send END signal , if connectionn is valid 
+               if @status != "ERROR" and not @outstream.nil? then
+                       BuildCommServer.send_end(@outstream)
+               end
+
+               # close outstream
+               if not @outstream.nil? then
+                       BuildCommServer.disconnect( @outstream )
+               end
+       end
+
+
+       # verify
+       def pre_verify
+               @log.info( "Verifying job input...", Log::LV_USER)
+
+               # check pkginfo.manifest
+               if not File.exist? "#{@source_path}/package/pkginfo.manifest"
+                       @log.error( "#{@source_path}/package/pkginfo.manifest doest not exist", Log::LV_USER)
+                       @status = "ERROR"
+                       return false
+               end
+
+               # set pkginfo
+               @pkginfo = PackageManifest.new("#{@source_path}/package/pkginfo.manifest")
+
+               # set up pkgsvr_client
+               @pkgsvr_client =  Client.new(@pkgserver_url, @job_working_dir, @log)
+               @pkgsvr_client.update
+
+               return true
+       end
+
+end
diff --git a/src/build_server/RemoteBuildJob.rb b/src/build_server/RemoteBuildJob.rb
new file mode 100644 (file)
index 0000000..8e9355b
--- /dev/null
@@ -0,0 +1,44 @@
+=begin
+ RemoteBuildJob.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "BuildJob.rb"
+require "utils.rb"
+
+class RemoteBuildJob < BuildJob
+       attr_accessor :id
+
+       # initialize
+       def initialize (id)
+               super()
+               @id = id
+               @type = nil
+               @outstream = nil
+       end
+end
diff --git a/src/build_server/SocketJobRequestListener.rb b/src/build_server/SocketJobRequestListener.rb
new file mode 100644 (file)
index 0000000..4cfa794
--- /dev/null
@@ -0,0 +1,251 @@
+=begin
+ SocketJobRequestListener.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+require "GitBuildJob.rb"
+require "LocalBuildJob.rb"
+require "JobLog.rb"
+require "BuildComm.rb"
+
+
+class SocketJobRequestListener
+
+       # initialize
+       def initialize (parent)
+               @parent_server = parent
+               @thread = nil
+               @finish_loop = false
+               @log = @parent_server.log
+       end
+
+       # start listening
+       def start()
+               @thread = Thread.new {
+                       main()          
+               }
+       end
+
+
+
+       # quit listening
+       def stop_listening()
+               @finish_loop = true
+       end
+       
+       private
+
+       # thread main  
+       def main()
+               # server open
+               begin
+                       server = BuildCommServer.new(@parent_server.port, @log)
+               rescue
+                       @log.info "Server creation failed"
+                       return
+               end
+
+               # loop
+               @log.info "Entering Control Listening Loop ... "        
+               @finish_loop = false
+               server.wait_for_connection(@finish_loop) do |req|
+                               handle_job_request( req )
+               end     
+
+               # quit
+               server.terminate
+       end
+
+
+       # wait for job requests
+       def wait_for_job_requests
+               req_list = []
+               req_list.push @tcp_server.accept                
+               
+               return req_list
+       end
+
+
+       # handle job request
+       def handle_job_request( req )
+
+               # read request
+               req_line = req.gets             
+               if req_line.nil? then return end
+
+               # parse request
+               cmd = ""
+               if req_line.split(",").count > 0 then
+                       cmd = req_line.split(",")[0].strip 
+               end
+               
+               case  cmd
+               when "BUILD"
+                       handle_cmd_build( req_line, req )
+               when "RESOLVE"
+                       handle_cmd_resolve( req_line, req )
+               when "QUERY"
+                       handle_cmd_query( req_line, req )
+               else
+                       @log.info "Received Unknown REQ: #{req_line}" 
+                       raise "Unknown request: #{req_line}"
+               end
+
+       end
+
+
+       # "BUILD"       
+       def handle_cmd_build( line, req )
+               tok = line.split(",").map { |x| x.strip }
+               if tok.count < 4 then 
+                       @log.info "Received Wrong REQ: #{line}" 
+                       raise "Invalid request format is used: #{line}"
+               end
+
+               case tok[1]
+               # BUILD,GIT,repos,commit,os,url,async
+               when "GIT"
+                       @log.info "Received BUILD GIT => #{tok[2]}"
+
+                       # check asynchronous job
+                       async = (not tok[6].nil? and tok[6]=="YES" ? true:false)        
+                       if async then
+                               new_job = GitBuildJob.new( tok[2], tok[3], tok[4], tok[5], [], @parent_server, nil, nil, false)
+                       else    
+                               new_job = GitBuildJob.new( tok[2], tok[3], tok[4], tok[5], [], @parent_server, nil, req, false)
+                       end
+                       BuildCommServer.send_begin(req)
+
+                       # start job. If log url is supported, show it
+                       if not @parent_server.job_log_url.empty? then
+                               new_job.log.info( "Added new job \"#{new_job.id}\"! Check following URL", Log::LV_USER)
+                               new_job.log.info( " * Log URL : #{@parent_server.job_log_url}/#{new_job.id}/log", Log::LV_USER)
+                       else
+                               new_job.log.info( "Added new job \"#{new_job.id}\"!", Log::LV_USER)
+                       end
+
+                       # if asynchronouse, quit connection
+                       if async then
+                               if not @parent_server.job_log_url.empty? then
+                                       req.puts ( "Info: Added new job \"#{new_job.id}\"! Check following URL")
+                                       req.puts ( "Info: * Log URL : #{@parent_server.job_log_url}/#{new_job.id}/log")
+                               else
+                                       req.puts( "Info: Added new job \"#{new_job.id}\"!")
+                               end
+
+                               BuildCommServer.send_end(req)
+                               BuildCommServer.disconnect(req)
+                       end     
+
+                       # add
+                       @parent_server.add_job( new_job )
+
+               # BUILD,LOCAL,path,os,url
+               when "LOCAL"
+                       @log.info "Received BUILD LOCAL => #{tok[2]}" 
+                       
+                       BuildCommServer.send_begin(req)
+                       @parent_server.add_job( 
+                               LocalBuildJob.new( tok[2], tok[3], tok[4], [], @parent_server, nil, req, false))
+               else
+                       @log.info "Received Wrong REQ: #{line}"
+                       raise "Invalid request format is used: #{line}"
+               end     
+       end
+
+
+       # "RESOLVE"     
+       def handle_cmd_resolve( line ,req)
+               tok = line.split(",").map { |x| x.strip }
+               if tok.count < 4 then 
+                       @log.info "Received Wrong REQ: #{line}" 
+                       raise "Invalid request format is used: #{line}"
+               end
+
+               case tok[1]
+               # RESOLVE,GIT,repos,commit,os,url
+               when "GIT"
+                       @log.info "Received RESOLVE GIT => #{tok[2]}"
+
+                       BuildCommServer.send_begin(req)
+                       @parent_server.add_job( 
+                               GitBuildJob.new( tok[2], tok[3], tok[4], tok[5], [], @parent_server, nil, req, true))
+               # RESOLVE,LOCAL,path,os,url
+               when "LOCAL"
+                       @log.info "Received RESOLVE LOCAL => #{tok[2]}" 
+
+                       BuildCommServer.send_begin(req)
+                       @parent_server.add_job( 
+                               LocalBuildJob.new( tok[2], tok[3], tok[4], [], @parent_server, nil, req, true))
+               else
+                       @log.info "Received Wrong REQ: #{line}" 
+                       raise "Invalid request format is used: #{line}"
+               end     
+       end
+
+
+       # "QUERY"
+       def handle_cmd_query( line, req )
+               tok = line.split(",").map { |x| x.strip }
+               if tok.count < 2 then 
+                       @log.info "Received Wrong REQ: #{line}" 
+                       raise "Invalid request format is used: #{line}"
+               end
+       
+               case tok[1]
+               # QUERY,JOB
+               when "JOB"
+                       #puts "Received QUERY JOB"
+
+                       BuildCommServer.send_begin(req)
+                       for job in @parent_server.working_jobs
+                               BuildCommServer.send(req,"WORKING,#{job.id},#{job.pkginfo.packages[0].source}")
+                       end
+                       for job in @parent_server.waiting_jobs
+                               BuildCommServer.send(req,"WAITING,#{job.id},#{job.pkginfo.packages[0].source}")
+                       end
+                       for job in @parent_server.remote_jobs
+                               BuildCommServer.send(req,"REMOTE ,#{job.id},#{job.pkginfo.packages[0].source}")
+                       end
+                       BuildCommServer.send_end(req)
+                       BuildCommServer.disconnect(req)
+
+               # QUERY,SYSTEM
+               when "SYSTEM"
+                       #puts "Received QUERY SYSTEM" 
+
+                       BuildCommServer.send_begin(req)
+                       BuildCommServer.send(req,"#{@parent_server.host_os},#{@parent_server.max_working_jobs}")
+                       BuildCommServer.send_end(req)
+                       BuildCommServer.disconnect(req)
+               else
+                       @log.info "Received Wrong REQ: #{line}" 
+                       raise "Invalid request format is used: #{line}"
+               end
+       end
+
+end
diff --git a/src/builder/Builder.rb b/src/builder/Builder.rb
new file mode 100644 (file)
index 0000000..a9e672c
--- /dev/null
@@ -0,0 +1,567 @@
+=begin
+ Builder.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/pkg_server"
+require "client"
+require "utils"
+require "PackageManifest"
+require "log"
+
+class Builder
+       private_class_method :new
+       attr_accessor :id, :pkgserver_url, :log
+
+       CONFIG_ROOT = Utils::HOME + "/.build_tools/builder"
+       @@instance_map = {}
+
+       # initialize
+       def initialize (id, pkgserver_url, log_path)
+               @id = id
+               @pkgserver_url = pkgserver_url
+               @host_os = Utils::HOST_OS
+               @log = Log.new(log_path)
+       end
+
+       
+       # create
+       def self.create (id, pkgserver_url, log_path)
+
+               # check builder config root
+               check_builder_config_root
+
+               # if exist , overwrite
+               if File.exist? "#{CONFIG_ROOT}/#{id}"
+                       FileUtils.rm_rf "#{CONFIG_ROOT}/#{id}"
+               end
+
+               # create new instance and return it
+               @@instance_map[id] = new( id, pkgserver_url, log_path )
+
+               # write config
+               write_builder_config( @@instance_map[id] )
+               return @@instance_map[id]
+       end
+
+
+       def self.remove( id )
+               # check builder config root
+               check_builder_config_root
+
+               # check id
+               if File.exist? "#{CONFIG_ROOT}/#{id}"
+                       FileUtils.rm_rf "#{CONFIG_ROOT}/#{id}"
+                       @@instance_map[id] = nil
+                       puts "Removed the builder \"#{id}\""
+               end
+       end
+
+
+       # get
+       def self.get( id )
+
+               # check instance first
+               if not @@instance_map[id] == nil
+                       return @@instance_map[id] 
+               end
+
+               # check builder config 
+               if not File.exist? "#{CONFIG_ROOT}/#{id}/builder.cfg" 
+                       raise RuntimeError, "The builder \"#{id}\" does not exist."
+               end
+
+               # get builder config and return its object
+               @@instance_map[id] = read_builder_config(id)
+
+               return @@instance_map[id]
+       end
+
+
+       # clean
+       def clean( src_path )
+
+               build_root_dir = "#{CONFIG_ROOT}/#{@id}/buildroot"
+
+               # create pkginfo
+        pkginfo = PackageManifest.new("#{src_path}/package/pkginfo.manifest")
+
+               # make clean
+           for pkg in pkginfo.packages
+                       FileUtils.rm_rf "#{src_path}/package/#{pkg.package_name}.package.linux"
+                       FileUtils.rm_rf "#{src_path}/package/#{pkg.package_name}.package.windows"
+                       FileUtils.rm_rf "#{src_path}/package/#{pkg.package_name}.package.darwin"
+               end
+               env_def = 
+                       "SRCDIR=\"#{src_path}\" "
+        build_command = "cd \"#{src_path}\";" + env_def + "./package/build.#{@host_os} clean"
+               if not Utils.execute_shell_with_log( build_command, @log )
+                       @log.error( "Failed on clean script", Log::LV_USER )
+                       return false
+               end
+
+               return true
+       end
+
+
+       # build
+       def build( src_path, os, clean, reverse_dep_check, pending_pkg_dir_list, ignore_rev_dep_build_list )
+
+               # create pkginfo
+        pkginfo = PackageManifest.new("#{src_path}/package/pkginfo.manifest")
+
+               # check there are packages which can be built
+               if not pkginfo.package_exist?(os, Utils::HOST_OS ) then
+                       @log.error( "There are no packages which can be built on this host OS: #{Utils::HOST_OS}")
+                       @log.error( " * Check \"Build-host-os\" in pkginfo.manifest" )
+                       return false
+               end
+
+               # set build root
+               if clean then
+                       build_root_dir = "#{CONFIG_ROOT}/#{@id}/temp_root"
+               else
+                       build_root_dir = "#{CONFIG_ROOT}/#{@id}/buildroot"
+               end
+
+        FileUtils.mkdir_p build_root_dir
+
+        local_pkg_list = []
+        pending_pkg_dir_list.each do |dir|
+            local_pkg_list += Dir.entries(dir).select{|e| e =~ /\.zip$/}.map{|p| dir + "/" + p}
+        end
+
+               # create client
+               @log.info( "Downloding client is initializing...", Log::LV_USER)
+               cl = Client.new(@pkgserver_url, build_root_dir, @log)
+               if clean then 
+                       cl.clean(true)
+               end
+        cl.update
+
+               # install build dependencies
+        package_overwrite_list = []
+               @log.info( "Installing dependent packages...", Log::LV_USER)
+               pkginfo.get_build_dependencies( os, @host_os ).each do |dep|
+                       if dep.target_os_list.count != 0 then
+                               dep_target_os = dep.target_os_list[0]
+                       else
+                               dep_target_os = os
+                       end
+                       @log.info( " * #{dep.package_name}", Log::LV_USER)
+
+            # get local dependent package 
+            pkgexp = Regexp.new("\/#{dep.package_name}_.*_#{dep_target_os}\.zip$")
+            package_overwrite_list += local_pkg_list.select{|l| l =~ pkgexp}
+
+            if not cl.install(dep.package_name, dep_target_os, true, false)  then
+                               @log.error( "Installing \"#{dep.package_name}\" failed!", Log::LV_USER)
+                               return false
+                       end
+               end
+
+        # overwrite local dependent packages
+        package_overwrite_list.each do |l|
+            cl.install_local_pkg(l,false)
+        end 
+
+               @log.info( "Downloading dependent source packages...", Log::LV_USER)
+        pkginfo.get_source_dependencies(os,@host_os).each do |dep|
+            @log.info( " * #{dep.package_name}", Log::LV_USER)
+
+            if cl.download_dep_source(dep.package_name).nil? then
+                @log.error( "Downloading \"#{dep.package_name}\" failed!", Log::LV_USER)
+                return false
+            end
+        end
+
+               # make clean
+               @log.info( "Make clean...", Log::LV_USER)
+           for pkg in pkginfo.packages
+                       FileUtils.rm_rf "#{src_path}/package/#{pkg.package_name}.package.linux"
+                       FileUtils.rm_rf "#{src_path}/package/#{pkg.package_name}.package.windows"
+                       FileUtils.rm_rf "#{src_path}/package/#{pkg.package_name}.package.darwin"
+               end 
+
+               # convert path if windows
+               if Utils::HOST_OS == "windows" then
+                       build_root_dir = Utils.get_unix_path( build_root_dir )
+               end
+               env_def = 
+                       "BUILD_TARGET_OS=#{os} \
+                        SRCDIR=\"#{src_path}\" \
+                        ROOTDIR=\"#{build_root_dir}\" "
+        build_command = "cd \"#{src_path}\";" + env_def + "./package/build.#{@host_os} clean"
+
+               if not Utils.execute_shell_with_log( build_command, @log )
+                       @log.error( "Failed on clean script", Log::LV_USER)
+                       return false
+               end
+
+               # make source package
+               @log.info( "Make source package...", Log::LV_USER)
+        build_command = "cd \"#{src_path}\";tar czf #{pkginfo.packages[0].source}_#{pkginfo.packages[0].version}.tar.gz --exclude=.git *"
+               if not Utils.execute_shell_with_log( build_command, @log )
+                       @log.error( "Failed on tar script", Log::LV_USER)
+                       return false
+               end
+
+               # execute build script
+               @log.info( "Make build...", Log::LV_USER)
+        build_command = "cd \"#{src_path}\";" + env_def + "./package/build.#{@host_os} build"
+               if not Utils.execute_shell_with_log( build_command, @log )
+                       @log.error( "Failed on build script", Log::LV_USER)
+                       return false
+               end
+               
+               # execute install script
+               @log.info( "Make install...", Log::LV_USER)
+        build_command = "cd \"#{src_path}\";" + env_def + "./package/build.#{@host_os} install"
+               if not Utils.execute_shell_with_log( build_command, @log )
+                       @log.error( "Failed on build script", Log::LV_USER)
+                       return false
+               end
+
+               # write pkginfo
+               @log.info( "Generatiing pkginfo.manifest...", Log::LV_USER)
+               if not write_pkginfo_files(pkginfo,os,src_path) then
+                       @log.error( "Failed to write pkginfo.manifest", Log::LV_USER)
+                       return false
+               end
+
+               # zip
+               @log.info( "Zipping...", Log::LV_USER)
+               make_zip(pkginfo,os,src_path)
+               
+               # check reverse dependecy if needed
+               if reverse_dep_check then
+                       if not check_reverse_build_dependency_fail_list(src_path, os, cl, true, ignore_rev_dep_build_list).empty? then
+                               return false
+                       end
+               end
+               return true
+       end
+
+    def build_resolve(src_path, os, pending_pkg_dir_list, ignore_rev_dep_build_list)
+        # clean build
+        if not build(src_path, os, true, false, pending_pkg_dir_list, ignore_rev_dep_build_list) then 
+            return nil
+        end
+        # init client
+        build_root_dir = "#{CONFIG_ROOT}/#{@id}/temp_root"
+        cl = Client.new(@pkgserver_url, build_root_dir, @log)
+        # rev build
+        return check_reverse_build_dependency_fail_list(src_path, os, cl, false, ignore_rev_dep_build_list )
+    end 
+
+
+       # reset
+       def reset()
+               build_root_dir = "#{CONFIG_ROOT}/#{@id}/buildroot"
+        temp_dir = cl.location
+        cl.location = build_root_dir
+        cl.clean(true)
+        cl.location = temp_dir
+       end
+
+
+       private
+
+
+       # check builder config root
+       def self.check_builder_config_root
+               if not File.exist? Builder::CONFIG_ROOT
+                       puts "Builder configuation is not found."
+                       puts "Creating new builder configuration... #{Builder::CONFIG_ROOT}"
+                       FileUtils.mkdir_p "#{Builder::CONFIG_ROOT}"
+               end
+       end
+
+
+       # write builder configuration
+       def self.write_builder_config( obj )
+               # create config folder
+               builder_dir = "#{CONFIG_ROOT}/#{obj.id}"
+               FileUtils.mkdir_p( "#{builder_dir}" )
+
+               # write configuration
+               File.open( "#{builder_dir}/builder.cfg", "w" ) do |f|
+                       f.puts "ID=#{obj.id}"
+                       f.puts "PSERVER_URL=#{obj.pkgserver_url}"
+                       f.puts "LOG-PATH=#{obj.log.path}"
+               end
+               puts "#{builder_dir}/builder.cfg"
+       end
+
+
+       # read builder configuration
+       def self.read_builder_config( id )
+               pkgserver_url=""
+
+               # read configuration
+               builder_dir = "#{CONFIG_ROOT}/#{id}"
+        log_path = nil
+               File.open( "#{builder_dir}/builder.cfg", "r" ) do |f|
+                       f.each_line do |l|
+                               if l.start_with?("PSERVER_URL=")
+                    pkgserver_url = l.split("=")[1].strip
+                elsif l.start_with?("LOG-PATH=")
+                    log_path = l.split("=")[1].strip 
+                    log_path = nil if log_path == "STDOUT" 
+                               else
+                                       next    
+                               end 
+                       end
+               end
+
+        if log_path.empty? then log_path = nil end
+               # create object & return it
+               return new( id, pkgserver_url, log_path )
+       end
+
+
+       # check reverse build dependency
+       def check_reverse_build_dependency_fail_list( parent_path, os, pkg_cl, immediately, ignore_rev_dep_build_list )
+               @log.info( "Checking reverse build dependency ...", Log::LV_USER)
+
+        reverse_fail_list = []
+
+               # install newly packages
+               for path in Dir.glob("*_*_#{os}.zip")
+                       # install
+                       pkg_cl.install_local_pkg( path, false )
+               end             
+
+               # get reverse-dependent source-codes
+        pkginfo = PackageManifest.new("#{parent_path}/package/pkginfo.manifest")
+               pkg_list = [] 
+               for pkg in pkginfo.packages
+                       pkg_list = pkg_list + pkg_cl.get_reverse_build_dependent_packages(pkg.package_name, os)
+            @log.info( "Extract reverse build dependency #{pkg.package_name} ...", Log::LV_USER)
+               end
+        pkg_list -= ignore_rev_dep_build_list
+               pkg_list.uniq!
+               
+               # download sources
+               src_path_hash = {}
+               pkg_list.each do |pkg|
+                       # download
+                       src_path = pkg_cl.download_source(pkg, os)
+            @log.info( "Downloaded #{pkg} source package to #{src_path}", Log::LV_USER)
+
+            if src_path_hash[src_path].nil? then 
+                src_path_hash[src_path] = [pkg]
+            else 
+                src_path_hash[src_path] += [pkg]
+            end 
+        end
+        src_path_list = src_path_hash.keys
+
+               # add jobs for building reverse-dependent
+               src_path_list.each do |path|
+                       # extract source package to test path
+                       @log.info( " * Extracting source ... #{path}", Log::LV_USER)
+                       test_src_path = "#{parent_path}/tmp_build"
+                       FileUtils.mkdir_p test_src_path
+                       Utils.execute_shell("cd \"#{test_src_path}\";tar xf #{path}")
+                       
+                       # build
+                       @log.info( " * Building source ... ", Log::LV_USER)
+                       result = build_test_with_pkg_client( pkg_cl, test_src_path, os, parent_path )
+                       FileUtils.rm_rf test_src_path
+                       if not result  then 
+                reverse_fail_list += src_path_hash[path]
+                               @log.error( "Build \"#{src_path_hash[path].join(", ")}\" test failed", Log::LV_USER)
+                if immediately then 
+                    return reverse_fail_list
+                end 
+            end
+        end
+
+               return reverse_fail_list.uniq
+       end
+
+
+       # build test
+       def build_test_with_pkg_client( pkg_cl, src_path, os,  parent_path)
+
+        local_pkg_list = []
+        local_pkg_list += Dir.entries(parent_path).select{|e| e =~ /\.zip$/}.map{|p| parent_path + "/" + p}
+
+               # create pkginfo
+        pkginfo = PackageManifest.new("#{src_path}/package/pkginfo.manifest")
+
+               # install build dependencies
+        package_overwrite_list = []
+               pkginfo.get_build_dependencies(os,@host_os).each do |dep|
+                       if dep.target_os_list.count != 0 then
+                               dep_target_os = dep.target_os_list[0]
+                       else
+                               dep_target_os = os
+                       end
+
+            # get local dependent package 
+            pkgexp = Regexp.new("\/#{dep.package_name}_.*_#{dep_target_os}\.zip$")
+            package_overwrite_list += local_pkg_list.select{|l| l =~ pkgexp}
+
+            pkg_cl.install(dep.package_name, dep_target_os, true, false)
+               end     
+
+        # overwrite local dependent packages
+        package_overwrite_list.each do |l|
+            @log.info( "Package overwrite ..#{l}", Log::LV_USER)
+            pkg_cl.install_local_pkg(l,false)
+        end 
+
+               # source download
+               pkginfo.get_source_dependencies(os,@host_os).each do |dep|
+            pkg_cl.download_dep_source(dep.package_name)
+               end
+
+               # execute build script
+               build_root_dir = pkg_cl.location
+               env_def = 
+                       "BUILD_TARGET_OS=#{os} \
+                        SRCDIR=\"#{src_path}\" \
+                        ROOTDIR=\"#{build_root_dir}\" "
+        build_command = "cd \"#{src_path}\";" + env_def + "./package/build.#{@host_os} build"
+               if not Utils.execute_shell_with_log( build_command, @log ) then
+                       @log.error( "Failed on build script", Log::LV_USER)
+                       return false
+               else
+                       return true
+               end
+
+       end
+
+
+       # write pkginfo.manifest and install/remove script
+       def     write_pkginfo_files(pkginfo,os,src_path)
+               for pkg in pkginfo.packages
+                       # skip if not support the target os
+                       if not pkg.os.include? os
+                               next
+                       end
+
+                       # install script files
+                       copy_post_install_script(pkg,os,src_path);
+                       copy_post_remove_script(pkg,os,src_path);
+
+                       # write manifest file
+                       install_dir = "#{src_path}/package/#{pkg.package_name}.package.#{os}"
+                       
+                       # if there is no intall directory, error
+                       if not File.exist? install_dir then
+                               @log.error( "Following directory must be created before writing pkginfo.manifest", Log::LV_USER)
+                               @log.error( " * package/#{pkg.package_name}.package.#{os}", Log::LV_USER)
+                               return false
+                       end
+               
+                       # write pkginfo.manifest        
+                       File.open("#{install_dir}/pkginfo.manifest", "w") do |f|
+                               pkg.print_to_file_with_os( f, os )
+                       end
+               end
+
+               return true
+       end
+
+
+       # copy post-install script
+       def     copy_post_install_script(pkg,os,src_path)
+               
+               tar = nil
+
+               if File.exist? "#{src_path}/package/#{pkg.package_name}.install.#{os}"
+                       src = "#{src_path}/package/#{pkg.package_name}.install.#{os}"
+               else
+                       src = nil
+               end
+
+               if not src.nil? then
+                       if os == "linux" or os == "darwin" then
+                               tar = "#{src_path}/package/#{pkg.package_name}.package.#{os}/install.sh"
+                       elsif os == "windows" then
+                               tar = "#{src_path}/package/#{pkg.package_name}.package.#{os}/install.BAT"
+                       else
+                               puts "Unknown OS: #{os} "
+                               return
+                       end
+
+                       FileUtils.cp(src, tar)
+               end     
+       
+               return
+       end
+
+
+       # copy post-remove script
+       def     copy_post_remove_script(pkg,os,src_path)
+               
+               tar = nil
+
+               if File.exist? "#{src_path}/package/#{pkg.package_name}.remove.#{os}"
+                       src = "#{src_path}/package/#{pkg.package_name}.remove.#{os}"
+               else
+                       src = nil
+               end
+
+               if not src.nil?
+            puts "------> #{src}"
+                       if os == "linux" or os == "darwin" then
+                               tar = "#{src_path}/package/#{pkg.package_name}.package.#{os}/remove.sh"
+                puts "-0--\==> #{tar}"
+                       elsif os == "windows" then
+                               tar = "#{src_path}/package/#{pkg.package_name}.package.#{os}/remove.BAT"
+                       else
+                               puts "Unknown OS: #{os} "
+                               return
+                       end
+
+                       FileUtils.cp(src, tar)
+               end     
+       end
+
+
+       # create package file
+       def     make_zip(pkginfo,os,src_path)
+               for pkg in pkginfo.packages
+                       # skip if not support the target os
+                       if not pkg.os.include? os
+                               next
+                       end
+
+                       # cd install dir
+                       install_dir = "#{src_path}/package/#{pkg.package_name}.package.#{os}"
+                       
+                       # zip   
+                       @log.info( "Creating package file ... #{pkg.package_name}_#{pkg.version}_#{os}.zip", Log::LV_USER)
+                       Utils.execute_shell("cd \"#{install_dir}\"; zip -r -y #{src_path}/#{pkg.package_name}_#{pkg.version}_#{os}.zip *")
+               end
+       end
+end
diff --git a/src/builder/CleanOptionParser.rb b/src/builder/CleanOptionParser.rb
new file mode 100644 (file)
index 0000000..31611fc
--- /dev/null
@@ -0,0 +1,47 @@
+=begin
+ CleanOptionParser.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'optparse'
+require 'logger'
+
+def parse()
+
+    #option parsing 
+    option = {}
+    optparse = OptionParser.new do |opts|
+        opts.banner = "Usage: pkg-clean"
+        opts.on('-h','--help', 'display this information') do 
+            puts opts
+            exit
+        end 
+    end 
+
+    optparse.parse!
+   return option
+end 
diff --git a/src/builder/optionparser.rb b/src/builder/optionparser.rb
new file mode 100644 (file)
index 0000000..05888f0
--- /dev/null
@@ -0,0 +1,62 @@
+=begin
+ optionparser.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'optparse'
+require 'logger'
+
+def parse()
+
+    #option parsing 
+    option = {}
+    optparse = OptionParser.new do |opts|
+        opts.banner = "Usage: pkg-build -u <remote_package_server_url> -o <os> -c -h"
+        opts.on('-u','--url <remote_package_server_url>', 'remote package server url') do |url|
+            option[:url] = url
+        end 
+        option[:os] = nil
+        opts.on('-o','--os <os>', 'operating system ') do |os|
+            option[:os] = os
+        end 
+        option[:clean] = false
+        opts.on('-c','--clean', 'clean build') do 
+            option[:clean] = true
+        end 
+        option[:rev] = false
+        opts.on('-r','--rev', 'reverse build dependency check') do 
+            option[:rev] = true
+        end 
+        opts.on('-h','--help', 'display this information') do 
+            puts opts
+            exit
+        end 
+    end 
+
+    optparse.parse!
+   return option
+end 
diff --git a/src/common/PackageManifest.rb b/src/common/PackageManifest.rb
new file mode 100644 (file)
index 0000000..4a9c2d3
--- /dev/null
@@ -0,0 +1,107 @@
+=begin
+ PackageManifest.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+require "parser"
+
+class PackageManifest
+       attr_accessor :packages
+
+       def initialize( file_path )
+               @pkg_map = Parser.read_pkginfo_list( file_path )
+               @packages = @pkg_map.values
+       end
+
+
+       # scan all build dependencies
+       def get_build_dependencies( target_os, host_os )
+               # for all
+               list = []
+               for pkg in @packages
+                       # package that has the target os
+                       if not pkg.os.include?(target_os)
+                               next
+                       end
+
+                       # package that has the host os
+                       if not pkg.build_host_os.include?(host_os)
+                               next
+                       end
+                       # package that has the target os
+                       for dep in pkg.build_dep_list
+                       #       if dep.target_os_list.include? target_os
+                                       list.push dep
+                       #       end
+                       end
+               end
+               list.uniq!
+               
+               return list
+       end     
+
+       
+       # scan all build dependencies
+       def get_source_dependencies( target_os, host_os )
+               # for all
+               list = []
+               for pkg in @packages
+                       # only package that used in target os
+                       if not pkg.os.include?(target_os)
+                               next
+                       end
+
+                       # package that has the host os
+                       if not pkg.build_host_os.include?(host_os)
+                               next
+                       end
+
+                       # package that has the target os
+                       for dep in pkg.source_dep_list
+                       #       if dep.target_os_list.include? target_os
+                                       list.push dep
+                       #       end
+                       end
+               end
+               list.uniq!
+
+               return list
+       end     
+
+
+       def package_exist?(target_os, host_os)
+               for pkg in @packages
+                       # only package that used in target os
+                       if pkg.os.include?(target_os) and 
+                               pkg.build_host_os.include?(host_os)
+                               return true
+                       end
+               end
+
+               return false
+       end     
+end
diff --git a/src/common/Version.rb b/src/common/Version.rb
new file mode 100644 (file)
index 0000000..3bdba12
--- /dev/null
@@ -0,0 +1,49 @@
+=begin
+ Version.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+
+class Version < Array
+       def initialize s
+       super(s.split('.').map { |e| e.to_i })   
+       end   
+       def < x     
+               (self <=> x) < 0   
+       end   
+       def <= x     
+               (self <=> x) <= 0   
+       end   
+       def > x     
+               (self <=> x) > 0   
+       end   
+       def >= x     
+               (self <=> x) >= 0   
+       end   
+       def == x     
+               (self <=> x) == 0   
+       end 
+end 
diff --git a/src/common/dependency.rb b/src/common/dependency.rb
new file mode 100644 (file)
index 0000000..a6e9499
--- /dev/null
@@ -0,0 +1,74 @@
+=begin
+  dependency.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+require "Version" 
+
+class Dependency
+    attr_accessor :package_name, :comp, :base_version, :target_os_list
+    def initialize (package_name, comp, base_version, target_os_list)
+        @package_name = package_name
+        @comp = comp
+        @base_version = base_version
+        @target_os_list = target_os_list
+    end 
+
+    def to_s
+        string = @package_name 
+        if not @comp.nil? and not @base_version.nil? then 
+            string = string + " ( #{@comp} #{@base_version} )" 
+        end
+        if not @target_os_list.empty? then 
+            string = string + " [ #{@target_os_list.join("|")} ]"
+        end 
+        return string
+    end 
+
+       def match? ver
+               if @base_version.nil? 
+                       return true
+               end
+
+               # compare to base version
+               if @comp == ">>"
+                       return Version.new(ver) > Version.new(@base_version)
+               elsif @comp == ">="
+                       return Version.new(ver) >= Version.new(@base_version)
+               elsif @comp == "=="
+                       return Version.new(ver) == Version.new(@base_version)
+               elsif @comp == "<="
+                       return Version.new(ver) <= Version.new(@base_version)
+               elsif @comp == "<<"
+                       return Version.new(ver) < Version.new(@base_version)
+               else
+                       return true
+               end     
+       end
+end 
+
diff --git a/src/common/log.rb b/src/common/log.rb
new file mode 100644 (file)
index 0000000..afa8fd7
--- /dev/null
@@ -0,0 +1,105 @@
+=begin
+ log.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require "logger"
+
+class Log
+
+       attr_accessor :path
+
+       # Log LEVEL
+       LV_NORMAL = 1
+       LV_USER = 2
+
+
+       # init
+       def initialize(path, lv=LV_USER)
+        @path = path
+               if @path.nil? then
+                       @logger = Logger.new(STDOUT)
+               else
+                       @logger = Logger.new(path, "monthly")
+               end
+               # if log level is bigger/equal to second out level
+               # , we will send the log to second-out
+               @second_out_level = lv
+               @second_out = nil
+               # diable logger format
+               @default_formatter = @logger.formatter
+               @no_prefix_formatter = proc do |severity, datetime, progname, msg|
+                       " >#{msg}"                      
+               end
+       end
+
+
+       def info(msg, lv=LV_NORMAL)
+        if @path.nil? then puts "Info: #{msg}"
+        else @logger.info msg end
+               if not @second_out.nil? and lv >= @second_out_level then 
+                       output_extra "Info: " + msg 
+               end
+       end     
+
+       def warn(msg, lv=LV_NORMAL) 
+        if @path.nil? then puts "Warn: #{msg}"
+               else @logger.warn msg end
+               if not @second_out.nil? and lv >= @second_out_level then
+                       output_extra "Warn: " + msg 
+               end
+       end     
+
+
+       def error(msg, lv=LV_NORMAL) 
+        if @path.nil? then puts "Error: #{msg}"
+               else @logger.error msg end
+               if not @second_out.nil? and lv >= @second_out_level then
+                       output_extra "Error: " + msg 
+               end
+       end
+
+
+       def output(msg, lv=LV_NORMAL) 
+        if @path.nil? then puts msg
+               else @logger.info msg end
+               if not @second_out.nil? and lv >= @second_out_level then
+                       output_extra msg 
+               end
+       end
+
+
+       def close
+               @second_out= nil
+       end
+
+
+       protected
+       def output_extra(msg)
+               #do nothing     
+       end     
+
+end
diff --git a/src/common/mail.rb b/src/common/mail.rb
new file mode 100644 (file)
index 0000000..a49c1d2
--- /dev/null
@@ -0,0 +1,86 @@
+=begin
+ mail.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'net/smtp'
+$LOAD_PATH.unshift File.dirname(__FILE__)
+require "mailConfig"
+
+class Mail 
+
+       def Mail.send_mail( mail_to, subject, contents ) 
+
+               if mail_to.nil? or mail_to.empty? \
+                               or subject.nil? or subject.empty? \
+                               or contents.nil? or contents.empty? then 
+                       return false
+               end 
+
+               message = <<MESSAGE_END
+From: #{SENDER}
+TO: #{mail_to}
+Subject: #{subject}
+
+#{contents}
+
+MESSAGE_END
+               
+               Mail.send_mail2( mail_to, message )
+       end
+
+       def Mail.send_mail2( mail_to_list, message )
+               if mail_to_list.empty? then 
+                       puts "There is no maintainer email address "
+               else
+                       begin 
+                       Net::SMTP.start('localhost') do |smtp|
+                       smtp.send_message( message, SENDER, mail_to_list) 
+                               end 
+                       rescue => e 
+                               puts "Can't send result email"
+                               puts e.message
+                       end
+               end
+       end
+
+       def Mail.parse_email( low_email_list )
+               mail_list = []
+               low_email_list.each do | low_email |  
+                       ms = low_email.index('<')
+                       me = low_email.index('>')
+                       if ms.nil? or me.nil? then  
+                               next 
+                       else 
+                               mail = low_email[(ms+1)..(me-1)] 
+                       end
+                       
+                       if mail.include?("@") then mail_list.push mail end
+               end 
+
+               return mail_list 
+       end
+end
diff --git a/src/common/mailConfig.rb b/src/common/mailConfig.rb
new file mode 100644 (file)
index 0000000..73fb8c3
--- /dev/null
@@ -0,0 +1,2 @@
+SENDER = "sdk.slp@samsung.com"
+SERVER_ADDR = "http://172.21.17.46:8080"
diff --git a/src/common/package.rb b/src/common/package.rb
new file mode 100644 (file)
index 0000000..122f977
--- /dev/null
@@ -0,0 +1,161 @@
+=begin
+ package.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+class Package
+    attr_accessor :package_name, :version, :os, :build_host_os, :maintainer, :attribute, :install_dep_list, :build_dep_list, :source_dep_list, :conflicts, :source, :src_path, :path, :origin, :checksum, :size, :description
+    def initialize (package_name)
+        @package_name = package_name
+        @version = ""
+        @os = ""
+        @build_host_os = []
+        @maintainer = ""
+        @attribute = []
+        @install_dep_list = []
+        @build_dep_list = []
+        @source_dep_list = []
+        @conflicts = []
+        @source = ""
+        @src_path = ""
+        @path = ""
+        @origin = ""
+        @checksum = ""
+        @size = ""
+        @description = ""
+    end 
+    def print
+        puts "Package : " + @package_name
+        if not @version.empty? then puts "Version : " + @version end 
+        if not @os.empty? then puts "OS : " + @os end 
+        if not @build_host_os.empty? then puts "Build-host-os : " + @build_host_os.join("|") end 
+        if not @maintainer.empty? then puts "Maintainer : " + @maintainer end 
+        if not @attribute.empty? then puts "Attribute : " + @attribute.join("|") end 
+        if not @install_dep_list.empty? then 
+            puts "Install-dependency : " + @install_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @build_dep_list.empty? then 
+            puts "Build-dependency : " + @build_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source_dep_list.empty? then 
+            puts "Source-dependency : " + @source_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @conflicts.empty? then 
+            puts "Conflicts : " + @conflicts.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source.empty? then puts "Source : " + @source end 
+        if not @src_path.empty? then puts "Src-path : " + @src_path end 
+        if not @path.empty? then puts "Path : " + @path end 
+        if not @origin.empty? then puts "Origin : " + @origin end 
+        if not @checksum.empty? then puts "SHA256 : " + @checksum end 
+        if not @size.empty? then puts "Size : " + @size end 
+        if not @description.empty? then puts "Description : " + @description end 
+    end 
+
+    def to_s
+        string =  "Package : " + @package_name
+        if not @version.empty? then string = string + "\n" +  "Version : " + @version end 
+        if not @os.empty? then string = string + "\n" + "OS : " + @os end 
+        if not @build_host_os.empty? then string = string + "\n" + "Build-host-os : " + @build_host_os.join("|") end 
+        if not @maintainer.empty? then string = string + "\n" + "Maintainer : " + @maintainer end 
+        if not @attribute.empty? then string = string + "\n" + "Attribute : " + @attribute.join("|") end 
+        if not @install_dep_list.empty? then 
+            string = string + "\n" + "Install-dependency : " + @install_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @build_dep_list.empty? then 
+            string = string + "\n" + "Build-dependency : " + @build_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source_dep_list.empty? then 
+            string = string + "\n" + "Source-dependency : " + @source_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @conflicts.empty? then 
+            string = string + "\n" + "Conflicts : " + @conflicts.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source.empty? then string = string + "\n" + "Source : " + @source end 
+        if not @src_path.empty? then string = string + "\n" + "Src-path : " + @src_path end 
+        if not @path.empty? then string = string + "\n" + "Path : " + @path end 
+        if not @origin.empty? then string = string + "\n" + "Origin : " + @origin end 
+        if not @checksum.empty? then string = string + "\n" + "SHA256 : " + @checksum end 
+        if not @size.empty? then string = string + "\n" + "Size : " + @size end 
+        if not @description.empty? then string = string + "\n" + "Description : " + @description end 
+        return string 
+    end 
+    def print_to_file(file)
+        file.puts "Package : " + @package_name
+        if not @version.empty? then file.puts "Version : " + @version end 
+        if not @os.empty? then file.puts "OS : " + @os end 
+        if not @build_host_os.empty? then file.puts "Build-host-os : " + @build_host_os.join("|") end 
+        if not @maintainer.empty? then file.puts "Maintainer : " + @maintainer end 
+        if not @attribute.empty? then file.puts "Attribute : " + @attribute.join("|") end 
+        if not @install_dep_list.empty? then 
+            file.puts "Install-dependency : " + @install_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @build_dep_list.empty? then 
+            file.puts "Build-dependency : " + @build_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source_dep_list.empty? then 
+            file.puts "Source-dependency : " + @source_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @conflicts.empty? then 
+            file.puts "Conflicts : " + @conflicts.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source.empty? then file.puts "Source : " + @source end 
+        if not @src_path.empty? then file.puts "Src-path : " + @src_path end 
+        if not @path.empty? then file.puts "Path : " + @path end 
+        if not @origin.empty? then file.puts "Origin : " + @origin end 
+        if not @checksum.empty? then file.puts "SHA256 : " + @checksum end 
+        if not @size.empty? then file.puts "Size : " + @size end 
+        if not @description.empty? then file.puts "Description : " + @description end 
+    end
+
+    def print_to_file_with_os(file,target_os)
+        file.puts "Package : " + @package_name
+        if not @version.empty? then file.puts "Version : " + @version end 
+        file.puts "OS : " + target_os
+        if not @build_host_os.empty? then file.puts "Build-host-os : " + @build_host_os.join("|") end 
+        if not @maintainer.empty? then file.puts "Maintainer : " + @maintainer end 
+        if not @attribute.empty? then file.puts "Attribute : " + @attribute.join("|") end 
+        if not @install_dep_list.empty? then 
+            file.puts "Install-dependency : " + @install_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @build_dep_list.empty? then 
+            file.puts "Build-dependency : " + @build_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source_dep_list.empty? then 
+            file.puts "Source-dependency : " + @source_dep_list.map {|x| x.to_s}.join(", ")
+        end 
+        if not @conflicts.empty? then 
+            file.puts "Conflicts : " + @conflicts.map {|x| x.to_s}.join(", ")
+        end 
+        if not @source.empty? then file.puts "Source : " + @source end 
+        if not @src_path.empty? then file.puts "Src-path : " + @src_path end 
+        if not @path.empty? then file.puts "Path : " + @path end 
+        if not @origin.empty? then file.puts "Origin : " + @origin end 
+        if not @checksum.empty? then file.puts "SHA256 : " + @checksum end 
+        if not @size.empty? then file.puts "Size : " + @size end 
+        if not @description.empty? then file.puts "Description : " + @description end 
+    end
+end 
diff --git a/src/common/parser.rb b/src/common/parser.rb
new file mode 100644 (file)
index 0000000..01f7acf
--- /dev/null
@@ -0,0 +1,239 @@
+=begin
+ parser.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+require "package"
+require "dependency"
+
+class Parser
+    def Parser.read_pkginfo_list (file)
+        pkglist = {}
+        File.open file,"r" do |f|
+            #variable initialize
+            package_name = ""
+            version = ""
+            os = ""
+            build_host_os = []
+            maintainer = ""
+            attribute = []
+            install_dep_list = [] 
+            build_dep_list = []
+            source_dep_list = []
+            conflicts = []
+            source = ""
+            src_path = ""
+            path = ""
+            origin = ""
+            checksum = ""
+            size = ""
+            description = ""
+
+            f.each_line do |l|
+                # separator
+                if l.strip.empty? then 
+                    #make package and initialize
+                    if not package_name.empty? and not os.empty? then 
+                        package = Package.new(package_name)
+                        if not version.empty? then package.version = version end 
+                        if not os.empty? then package.os = os end 
+                        if not build_host_os.empty? then package.build_host_os = build_host_os end 
+                        if not maintainer.empty? then package.maintainer = maintainer end 
+                        if not attribute.empty? then package.attribute = attribute end 
+                        if not install_dep_list.empty? then package.install_dep_list = install_dep_list end 
+                        if not build_dep_list.empty? then package.build_dep_list = build_dep_list end 
+                        if not source_dep_list.empty? then package.source_dep_list = source_dep_list end 
+                        if not conflicts.empty? then package.conflicts = conflicts end 
+                        if not source.empty? then package.source = source end 
+                        if not src_path.empty? then package.src_path = src_path end 
+                        if not path.empty? then package.path = path end 
+                        if not origin.empty? then package.origin = origin end 
+                        if not checksum.empty? then package.checksum = checksum end 
+                        if not size.empty? then package.size = size end 
+                        if not description.empty? then package.description = description end 
+                        pkglist[[package_name,os]] = package
+                        package_name = ""
+                        version = ""
+                        os = ""
+                        bulid_host_os = []
+                        maintainer = ""
+                        attribute = []
+                        install_dep_list = [] 
+                        build_dep_list = []
+                        source_dep_list = []
+                        conflicts = []
+                        source = ""
+                        src_path = ""
+                        path = ""
+                        origin = ""
+                        checksum = ""
+                        size = ""
+                        description = ""
+                    end 
+                    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 
+                    package_name = l.sub(/^[ \t]*Package[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Version/i then 
+                    version = l.sub(/^[ \t]*Version[ \t]*:[ \t]*/i,"").strip 
+                    disc_on=false
+                when /^OS/i then 
+                    os = l.sub(/^[ \t]*OS[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Build-host-os/i then 
+                    build_host_os = l.sub(/^[ \t]*Build-host-os[ \t]*:[ \t]*/i,"").tr(" \t\n\r", "").split("|")
+                    disc_on=false
+                when /^Maintainer/i then 
+                    maintainer = l.sub(/^[ \t]*Maintainer[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Attribute/i then 
+                    attribute = l.sub(/^[ \t]*Attribute[ \t]*:[ \t]*/i,"").tr(" \t\n\r","").split("|")
+                    disc_on=false
+                when /^Install-dependency/i then 
+                    install_dep_list = dep_parser l.sub(/^[ \t]*Install-dependency[ \t]*:[ \t]*/i,"").split(',')
+                    disc_on=false
+                when /^Build-dependency/i then 
+                    build_dep_list = dep_parser l.sub(/^[ \t]*Build-dependency[ \t]*:[ \t]*/i,"").split(',')
+                    disc_on=false
+                when /^Source-dependency/i then 
+                    source_dep_list = dep_parser l.sub(/^[ \t]*Source-dependency[ \t]*:[ \t]*/i,"").split(',')
+                    disc_on=false
+                when /^Conflicts/i then 
+                    conflicts = dep_parser l.sub(/^[ \t]*Conflicts[ \t]*:[ \t]*/i,"").split(',')
+                    disc_on=false
+                when /^Source/i then 
+                    source = l.sub(/^[ \t]*Source[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Src-path/i then 
+                    src_path = l.sub(/^[ \t]*Src-path[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Path/i then 
+                    path = l.sub(/^[ \t]*Path[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Origin/i then 
+                    origin = l.sub(/^[ \t]*Origin[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^SHA256/i then 
+                    checksum = l.sub(/^[ \t]*SHA256[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Size/i then 
+                    size = l.sub(/^[ \t]*Size[ \t]*:[ \t]*/i,"").strip
+                    disc_on=false
+                when /^Description/i then 
+                    description = l.sub(/^[ \t]*Description[ \t]*:[ \t]*/i,"")
+                    disc_on=true
+                else   
+                    if disc_on then 
+                        description = description + l
+                    else 
+                        puts "unknown section : #{l}"
+                    end
+                end 
+
+            end 
+            #i  essent
+
+            # check last package 
+            if not package_name.empty? and not os.empty? then 
+                package = Package.new(package_name)
+                if not version.empty? then package.version = version end 
+                if not os.empty? then package.os = os end 
+                if not build_host_os.empty? then package.build_host_os = build_host_os end 
+                if not maintainer.empty? then package.maintainer = maintainer end 
+                if not attribute.empty? then package.attribute = attribute end 
+                if not install_dep_list.empty? then package.install_dep_list = install_dep_list end 
+                if not build_dep_list.empty? then package.build_dep_list = build_dep_list end 
+                if not source_dep_list.empty? then package.source_dep_list = source_dep_list end 
+                if not conflicts.empty? then package.conflicts = conflicts end 
+                if not source.empty? then package.source = source end 
+                if not src_path.empty? then package.src_path = src_path end 
+                if not path.empty? then package.path = path end 
+                if not origin.empty? then package.origin = origin end 
+                if not checksum.empty? then package.checksum = checksum end 
+                if not size.empty? then package.size = size end 
+                if not description.empty? then package.description = description end 
+                pkglist[[package_name,os]] = package
+            end 
+        end 
+        return pkglist
+    end
+
+    def Parser.read_pkginfo (file)
+        return read_pkg_list(file).values[0]
+    end 
+
+    def Parser.read_pkg_list (file)
+        result = {}
+        read_pkginfo_list(file).values.each { |x| result[x.package_name]=x }
+        return result
+    end 
+
+    private
+    def Parser.dep_parser (string_list)
+        dependency_list = []
+        string_list.each do |dep|
+            #variable initialize
+            package_name = ""
+            comp = nil
+            base_version = nil
+            target_os_list = []
+            #string trim
+            dependency = dep.tr " \t\n", ""
+            #version extract
+            vs = dependency.index('(') 
+            ve = dependency.index(')') 
+            if not vs.nil? and not ve.nil? then 
+                comp = dependency[(vs+1)..(vs+2)]
+                base_version = dependency[(vs+3)..(ve-1)]
+            end 
+            #os list extract
+            os = dependency.index('[') 
+            oe = dependency.index(']') 
+            if not os.nil? and not oe.nil? then 
+                target_os_list = dependency[(os+1)..(oe-1)].split("|")
+            end 
+            # package_name extract
+            pe = dependency.index(/[\]\[\)\(]/)
+            if pe.nil?
+                package_name = dependency
+            else
+                package_name = dependency[0..pe-1]
+            end
+            #package_name check
+            if not package_name.empty? then 
+                dependency_list.push Dependency.new(package_name,comp,base_version,target_os_list)
+            end 
+        end 
+        return dependency_list
+    end 
+end 
diff --git a/src/common/utils.rb b/src/common/utils.rb
new file mode 100644 (file)
index 0000000..24b12ff
--- /dev/null
@@ -0,0 +1,220 @@
+=begin
+ utils.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+class Utils
+
+       if defined?(HOST_OS).nil? then
+               case `uname -s`.strip
+                       when "Linux"
+                               HOST_OS = "linux"
+                       when /MINGW32.*/
+                               HOST_OS = "windows"
+                       when "Darwin"
+                               HOST_OS = "darwin"
+                       else
+               end  
+       end
+
+       # set static variable in WORKING_DIR, HOME 
+       if defined?(WORKING_DIR).nil? then WORKING_DIR = Dir.pwd end 
+       if defined?(HOME).nil? then 
+               # get home directory, using Dir.chdir
+               Dir.chdir
+               HOME = Dir.pwd
+               Dir.chdir WORKING_DIR 
+       end
+
+    def Utils.create_uniq_name      
+        time = Time.new     
+        # uniq snapshot_name name is year_month_day_hour_min_sec_microsec       
+        return time.strftime("%m%d%H%M%S") + time.usec.to_s()        
+    end
+
+    def Utils.is_url_remote(url)
+        if url.nil? then
+            return false
+        end
+
+        protocol = url.split(':')[0]
+
+        case protocol
+        when "http" then
+            return true
+        else 
+            return false
+        end
+    end
+
+    # if source_ver > target_ver, return -1
+    # if source_ver < target_ver, return 1
+    # if source_ver == target_ver, return 0
+    def Utils.compare_version(source_ver, target_ver)
+        sver = source_ver.split('-')[0]
+        tver = target_ver.split('-')[0]
+
+        arr_sver = sver.split('.')
+        arr_tver = tver.split('.')
+
+        slen = arr_sver.length
+        tlen = arr_tver.length
+        len = tlen 
+
+        if slen > tlen then
+            gap = slen - tlen
+            gap.times do
+                arr_tver.push("0")
+            end
+            len = slen
+        elsif tlen > slen then
+            gap = tlen - slen
+            gap.times do
+                arr_sver.push("0")
+            end
+            len = tlen
+        end 
+
+        len.times do |i|
+            if arr_sver[i].to_i < arr_tver[i].to_i then
+                return 1
+            elsif arr_sver[i].to_i > arr_tver[i].to_i then
+                return -1
+            end
+        end
+
+        return 0
+       end
+
+
+    def Utils.execute_shell(cmd)
+        ret = false
+               if HOST_OS.eql? "windows" then
+                       mingw_path = "sh.exe -c "
+                       cmd = cmd.gsub("\"", "\\\"")
+            cmd = mingw_path + "\"#{cmd}\""
+               end
+
+               system "#{cmd}"
+        if $?.to_i == 0 then ret = true else ret = false end 
+               
+               return ret
+       end
+
+
+    def Utils.execute_shell_return(cmd)
+               result_lines = []
+
+               if HOST_OS.eql? "windows" then
+                       mingw_path = "sh.exe -c "
+                       cmd = cmd.gsub("\"", "\\\"")
+            cmd = mingw_path + "\"#{cmd}\""
+               end
+
+               # get result
+               IO.popen("#{cmd} 2>&1") { |io|
+                       io.each do |line|
+                               result_lines.push line
+                       end
+               }
+               
+        if $?.to_i == 0 then 
+                       return result_lines
+               else 
+                       return nil
+               end 
+       end
+
+    def Utils.execute_shell_return_ret(cmd)
+               if HOST_OS.eql? "windows" then
+                       mingw_path = "sh.exe -c "
+                       cmd = cmd.gsub("\"", "\\\"")
+            cmd = mingw_path + "\"#{cmd}\""
+               end
+
+        return `#{cmd}`
+    end
+
+       def Utils.execute_shell_with_log(cmd, log)
+
+               if HOST_OS.eql? "windows" then
+                       mingw_path = "sh.exe -c "
+                       cmd = cmd.gsub("\"", "\\\"")
+            cmd = mingw_path + "\"#{cmd}\""
+               end
+
+               # print log
+               IO.popen("#{cmd} 2>&1") { |io|
+                       io.each do |line|
+                               log.output line
+                       end
+               }
+               
+        if $?.to_i == 0 then 
+                       return true 
+               else 
+                       return false 
+               end 
+       end
+
+
+       def Utils.is_absolute_path(path)
+               if HOST_OS.eql? "linux" or HOST_OS.eql? "darwin" then  
+                       # if path start "/" then absoulte path
+                       if path.start_with?("/") then
+                               return true
+                       else
+                               return false 
+                       end
+               elsif HOST_OS.eql? "windows" then 
+                       # if path start "c:/" or "D:/" or ... then absoulte path
+                       if path =~ /^[a-zA-Z]:[\/]/ then
+                               return true
+                       else
+                               return false
+                       end
+               else 
+                       puts "HOST_OS is invalid"
+               end
+       end
+
+
+       # this will be used on MinGW/MSYS
+       def Utils.get_unix_path(path)
+               if HOST_OS.eql? "linux" or HOST_OS.eql? "darwin" then  
+                       return path
+               elsif HOST_OS.eql? "windows" then
+                       new_path = path
+                       if is_absolute_path( new_path ) then
+                               new_path = "/" + new_path[0,1] + new_path[2..-1]
+                       end
+                       return new_path
+               else 
+                       puts "HOST_OS is invalid"
+                       return path
+               end
+       end
+end
diff --git a/src/pkg_server/client.rb b/src/pkg_server/client.rb
new file mode 100644 (file)
index 0000000..8bffbd2
--- /dev/null
@@ -0,0 +1,1472 @@
+
+=begin
+ client.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require "fileutils"
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "downloader"
+require "installer"
+require "serverConfig"
+require "package"
+require "parser"
+require "utils"
+require "log"
+require "Version"
+
+class Client
+
+    # constant
+    SUPPORTED_OS = ["linux", "windows", "darwin"]
+    PKG_LIST_FILE_PREFIX = "pkg_list_"
+    INSTALLED_PKG_LIST_FILE = "installedpackage.list"
+    CONFIG_PATH = "#{$build_tools}/client"
+    PACKAGE_INFO_DIR = ".info"
+    DEFAULT_INSTALL_DIR = "#{Utils::HOME}/build_root"
+    DEFAULT_SERVER_ADDR = "http://172.21.17.55/dibs/unstable"
+    
+    attr_accessor :server_addr, :location, :pkg_hash_os, :is_server_remote, :installed_pkg_hash_loc, :archive_pkg_list, :all_dep_list, :log
+
+    public
+    # initialize
+    # create "remote package hash" and "installed package hash"
+    # @server_addr = server address (can be included distribution, snapshot)
+    # @location = client location (download and install file to this location)
+    def initialize(server_addr, location, logger)
+
+        # create directory
+               if not File.exist? CONFIG_PATH then FileUtils.mkdir_p "#{CONFIG_PATH}" end
+
+        # set default server address, location
+        if server_addr.nil? then server_addr = get_default_server_addr() end
+        if location.nil? then location = get_default_inst_dir() end
+
+        # chop server address, if end with "/"        
+        if server_addr.strip.end_with? "/" then server_addr = server_addr.chop end
+
+        @server_addr = server_addr
+        @location = location
+        @pkg_hash_os = {}
+        @installed_pkg_hash_loc = {}
+        @archive_pkg_list = []
+        @all_dep_list = []
+        @is_server_remote = Utils.is_url_remote(server_addr)
+
+        # set log
+        if logger.nil? or logger.class.to_s.eql? "String" then
+           @log = Log.new(logger)
+        else
+           @log = logger
+        end
+
+        FileInstaller.set_logger(@log)
+        FileDownLoader.set_logger(@log)
+
+        # read installed pkg list, and create hash
+        FileUtils.mkdir_p "#{@location}"
+        create_installed_pkg_hash()
+       
+        # readk remote pkg list, and hash list
+        create_remote_pkg_hash(false)
+        @log.info "Initialize - #{server_addr}, #{location}"
+    end
+
+    public
+    # update package list from server
+    def update()
+        if not create_remote_pkg_hash(true) then
+            @log.error "\"#{@server_addr}\" does not have package list file properly."
+            return false
+        end
+        create_default_config(@server_addr)
+        @log.info "Update package list from \"#{@server_addr}\".. OK"
+        return true
+    end
+
+    public
+    # download package
+    def download(pkg_name, os, trace)
+
+        dependent_pkg_list = []
+
+        # get dependent list
+        if trace then
+            dependent_pkg_list = get_install_dependent_packages(pkg_name, os, true, false)
+            if dependent_pkg_list.nil? then
+                @log.error "Failed to get dependency for \"#{pkg_name}\" package"
+                return false
+            end
+        else dependent_pkg_list = [pkg_name] end
+
+        surl = nil
+        addr_arr = @server_addr.split('/')
+        if addr_arr[-2].eql? "snapshots" then
+            surl = @server_addr + "/../.."
+        else 
+            surl = @server_addr
+        end
+
+        # download files
+        file_local_path = []
+        dependent_pkg_list.each do |p|
+            pkg_path = get_attr_from_pkg(p, os, "path")
+            pkg_ver = get_attr_from_pkg(p, os, "version")
+            url = surl + pkg_path
+            filename = pkg_path.split('/')[-1]
+            if not FileDownLoader.download(url, @location) then
+                @log.error "Failed download #{pkg_name} [#{pkg_ver}]"
+                return nil
+            end
+
+            file_local_path.push(File.join(@location, filename))
+            @log.info "Downloaded \"#{pkg_name} [#{pkg_ver}]\" package file.. OK"
+            @log.info "  [path : #{file_local_path.join(", ")}]"
+        end
+
+        return file_local_path
+    end
+
+    public
+    # download source package
+    def download_source(pkg_name, os)
+
+        # get source file path
+        src_path = get_attr_from_pkg(pkg_name, os, "src_path")
+        if src_path.nil? or src_path.empty? then
+            @log.error "#{pkg_name} package does not have source"
+            return nil
+        end  
+        file_url = nil
+
+        addr_arr = @server_addr.split('/')
+        if addr_arr[-2].eql? "snapshots" then
+            surl = @server_addr + "/../.." + src_path
+        else 
+            surl = @server_addr + src_path
+        end
+
+        # download file
+        filename = src_path.split('/')[-1]
+        if not FileDownLoader.download(surl, @location) then
+            @log.error "Failed download #{pkg_name} source"
+            return nil
+        end
+        file_local_path = File.join(@location, filename)
+        @log.info "Downloaded source of #{pkg_name} package.. OK"
+        @log.info "  [path : #{file_local_path}]"
+
+        return file_local_path
+    end
+    
+    public
+    # download dependent source
+    def download_dep_source(file_name)
+
+        file_url = nil
+
+        addr_arr = @server_addr.split('/')
+        if addr_arr[-2].eql? "snapshots" then
+            file_url = @server_addr + "/../../source/" + file_name
+        else 
+            file_url = @server_addr + "/source/#{file_name}"
+        end
+        if not FileDownLoader.download(file_url, @location) then
+            @log.error "Failed download #{file_name}"
+            return nil
+        end
+        file_local_path = File.join(@location, file_name)
+        @log.info "Downloaded \"#{file_name}\" source file.. OK"
+        @log.info "  [path : #{file_local_path}]"
+
+        return file_local_path
+    end
+
+    public
+    # check archive file
+    def check_archive_file(file_name)
+
+        result = false
+        filename = "archive_pkg_list"
+        local_file_path = File.join(CONFIG_PATH, filename)
+        if File.exist? local_file_path then
+            File.open(local_file_path, "r") do |f|
+                f.each_line do |l|
+                    if l.strip.eql? file_name.strip then 
+                        result = true
+                        break
+                    end     
+                end
+            end
+        end
+        return result
+    end
+
+    public
+    # upload package
+    def upload(ssh_alias, id, binary_path_list, source_path_list, verify)
+
+        # check source path list
+        if source_path_list.nil? or source_path_list.empty? then
+            @log.error "source package path should be set."
+            return nil
+        end
+
+        # verify ssh alias
+        verify = false
+        hostfound = false
+        sshconfig = "#{Utils::HOME}/.ssh/config"
+        File.open(sshconfig, "r") do |f|
+            f.each_line do |l|
+                if l.strip.upcase.start_with? "HOST" then
+                    al = l.strip.split(' ')[1].strip
+                    if al.eql? ssh_alias then hostfound = true
+                    else next end
+                end
+            end
+        end
+
+        if not hostfound then
+            @log.error "\"#{ssh_alias}\" does not exist in \".ssh/config\" file"
+            return nil
+        end
+
+        # get distribution from server addr 
+        dist = get_distribution()
+        if dist.nil? then
+            @log.error "Distribution is nil"
+            return nil
+        end
+
+        serveraddr = @server_addr
+        snapshot = nil
+        if serveraddr.include? "snapshots" then snapshot = serveraddr.split("/")[-1] end
+
+        # set server homd directory
+        server_home = `ssh #{ssh_alias} pwd`
+               server_home = server_home.strip
+
+        # set "pkg-svr" file path 
+               # if pkg-svr exist in path then using pkg-svr
+        result = `ssh #{ssh_alias} which pkg-svr`
+        if not( result.nil? or result.empty? or result.strip.empty? ) then 
+                               pkg_svr = "pkg-svr"
+               else
+                       # if pkg-svr not exist in path then try ~/tizen_sdk/dev_tools/pkg-svr
+                       result = `ssh #{ssh_alias} which #{server_home}/tizen_sdk/dev_tools/pkg-svr`
+               if not( result.nil? or result.empty? or result.strip.empty? ) then 
+                               pkg_svr = "#{server_home}/tizen_sdk/dev_tools/pkg-svr"
+                       else 
+               @log.error "Can't find server's pkg-svr command"
+               return nil
+                       end
+        end
+        pkg_svr = "#{server_home}/tizen_sdk/dev_tools/pkg-svr"
+
+        # set incoming directory (~/.build_tools/pkg_server/#{id}/incoming)        
+        incoming_path = "#{server_home}/.build_tools/pkg_server/#{id}/incoming"
+
+        # set pkg-svr register command
+        register_command = "#{pkg_svr} register -i #{id} -d #{dist}"
+
+        # upload source package (scp)
+        server_src_pkg_list_command = "\""
+        source_path_list.each do |spath|
+            # set source package file path for server filesystem
+            src_file_name = File.basename(spath)
+            server_src_pkg_path = "#{incoming_path}/#{src_file_name}"
+            server_src_pkg_list_command = server_src_pkg_list_command + server_src_pkg_path + ","
+            # upload source package
+            if File.exist? spath then
+                system "scp #{spath} #{ssh_alias}:#{server_src_pkg_path}"
+            else
+                @log.error "#{spath} file does not exist"
+                return nil
+            end
+        end
+
+        server_src_pkg_list_command = server_src_pkg_list_command.strip
+        if server_src_pkg_list_command.end_with? "," then
+            server_src_pkg_list_command = server_src_pkg_list_command.chop + "\""
+        else
+            server_src_pkg_list_command = server_src_pkg_list_command + "\""
+        end
+
+        # add src package list to register command
+        register_command = register_command + " -s #{server_src_pkg_list_command} -g"
+
+        # upload binary package (scp)
+        if not binary_path_list.nil? then
+            server_bin_pkg_list_command = "\""
+            binary_path_list.each do |bpath|
+                bin_file_name = File.basename(bpath)
+                bin_pkg_name = bin_file_name.split("_")[0]
+                if verify then
+                    if not verify_upload(bin_pkg_name, bpath) then
+                        @log.error "Failed to verify \"#{bpath}\" file"
+                        return nil
+                    end
+                end
+
+                server_bin_pkg_path = "#{incoming_path}/#{bin_file_name}"
+                server_bin_pkg_list_command = server_bin_pkg_list_command + server_bin_pkg_path + ","
+                # upload binary package
+                if File.exist? bpath then
+                    Utils.execute_shell("cd #{File.dirname(bpath)};scp #{File.basename(bpath)} #{ssh_alias}:#{server_bin_pkg_path}")
+                else
+                    @log.error "#{bpath} file does not exist"
+                    return nil
+                end
+            end
+
+            server_bin_pkg_list_command = server_bin_pkg_list_command.strip
+            if server_bin_pkg_list_command.end_with? "," then
+                server_bin_pkg_list_command = server_bin_pkg_list_command.chop + "\""
+            else 
+                server_bin_pkg_list_command = server_bin_pkg_list_command + "\""
+            end
+
+            # add bin package list to register command
+            register_command = register_command + " -p #{server_bin_pkg_list_command}"
+        end
+
+        @log.info "register_command : #{register_command}"
+               
+        # register packages to server
+        result = `ssh #{ssh_alias} #{register_command}`
+        if result.strip.include? "Error occured" then 
+            puts result
+            return nil 
+        end
+
+        # parsing snapshot url to show user
+        serveraddr = @server_addr
+        arr = serveraddr.split("/")
+        if serveraddr.include? "snapshots" then sid = arr[-4]
+        else sid = arr[-2] end
+        i = serveraddr.index(sid)
+        serveraddr = serveraddr[0..i-1]
+        serveraddr = serveraddr + id + "/" + dist
+
+        addr = []
+        result2 = ""
+        arr_re = result.split("\n")
+        arr_re.each do |l|
+            l = l.strip
+            if l.start_with? "snapshot is generated :" then
+                addr = l.split(":")[1].split("/")
+                if addr.include? dist then
+                    i = addr.index(dist)
+                    addr = addr[i+1..-1]
+                    str = ""
+                    addr.each do |l| str = str + "/" + l end
+                    str = serveraddr.strip + str
+                    result2 = result2 + str +"\n"
+                end
+            end
+        end
+
+        @log.info "Upload packages.. OK"
+        @log.info "  [#{binary_path_list.join(", ")}]"
+        @log.info "  [#{source_path_list.join(", ")}]"
+        return result2
+    end
+
+    private
+    # verify package before uploading
+    def verify_upload(pkg_name, pkg_path)
+
+        manifest_file = "pkginfo.manifest"
+        uniq_name = Utils.create_uniq_name
+        path = Utils::HOME + "/tmp/#{uniq_name}"
+        FileUtils.mkdir_p "#{path}"
+        if not FileInstaller.extract_specified_file(pkg_path, manifest_file, path) then
+            @log.error "The \"pkginfo.manifest\" file does not exist in \"#{pkg_path}\""
+            return false
+        end
+        manifest_path = File.join(path, manifest_file)
+        pkg_hash = Parser.read_pkg_list(manifest_path)
+        FileUtils.rm_f(manifest_path)
+        FileUtils.remove_dir(path, true)
+
+        new_pkg_ver = pkg_hash[pkg_name].version
+        new_pkg_install_dep_list = pkg_hash[pkg_name].install_dep_list
+        os = pkg_hash[pkg_name].os
+
+        list = get_all_reverse_install_dependent_packages_remote(pkg_name, os, true)
+
+        if not list.nil? then 
+            list.each do |p|
+                ilist = get_attr_from_pkg(p, os, "install_dep_list")
+                if ilist.nil? then next end
+                ilist.each do |l|
+                    if l.package_name.eql? pkg_name then
+                        if not l.match? new_pkg_ver then
+                            @log.error "\"#{p}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version})"
+                            return false
+                        end
+                    end
+                end
+            end
+        end
+
+        if not new_pkg_install_dep_list.nil? then
+            new_pkg_install_dep_list.each do |l|
+                if not check_remote_pkg(l.package_name, os) then
+                    @log.error "\"#{pkg_name}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version}), but \"#{l.package_name}\" is not exist on server"
+                    return false
+                end
+                rver = get_attr_from_pkg(l.package_name, os, "version")
+                if not l.match? rver then
+                    @log.error "\"#{pkg_name}\" package has following install dependency : #{l.package_name} (#{l.comp} #{l.base_version})"
+                    return false
+                end
+            end
+        end
+
+        @log.info "Passed to verify packages for uploading.. OK"
+        return true
+    end
+
+    private    
+    # get distribution
+    def get_distribution()
+        server = @server_addr
+        if server.nil? or server.empty? then
+            @log.error "Server addr is nil"
+            return nil
+        end
+
+        dist = ""
+        server_arr = server.split("/")
+        if server_arr.include? "snapshots" then
+            i = server_arr.index("snapshots")
+            dist = server_arr[i-1]
+        else dist = File.basename(server) end
+
+        return dist
+    end
+
+    public
+       # install package
+    # install all install dependency packages
+    def install(pkg_name, os, trace, force)
+
+        if trace.nil? then trace = true end
+        if force.nil? then force = false end
+
+        # check meta package
+        is_meta_pkg = check_meta_pkg(pkg_name, os)
+        if is_meta_pkg then trace = true end
+        
+        pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+        if pkg_ver.nil? or pkg_ver.empty? then
+            @log.error "#{pkg_name} package does not exist in remote package list"
+            return false
+        end
+
+        compare_result = compare_version_with_installed_pkg(pkg_name, pkg_ver)
+        if not force then
+            case compare_result
+            when -1 then
+                @log.warn "\"#{pkg_name}\" package version is bigger then remote package version"
+                return true
+            when 0 then
+                @log.warn "\"#{pkg_name}\" package version is same with remote package version"
+                return true
+            when 1, 2 then
+            end
+        end
+
+        # if enable trace, crate all dependent package list
+        if trace then
+            dependent_pkg_list = get_install_dependent_packages(pkg_name, os, true, force)
+            if dependent_pkg_list.nil? then
+                @log.error "Failed to get dependency for \"#{pkg_name}\" package"
+                return false
+            end
+        else
+            dependent_pkg_list = [pkg_name]
+        end
+
+        # if meta package, dependent list does not need to include self name
+        #if is_meta_pkg then
+        #    dependent_pkg_list.delete(pkg_name.strip)
+        #end
+
+        # TODO: need to compare dependent package version
+        # install packages including dependent packages
+        dependent_pkg_list.each do |pkg|
+            if not install_pkg(pkg, os, force) then 
+                @log.error "#{pkg} does not exist"
+                return false
+            end
+            add_pkg_info(pkg, os)
+        end
+        write_pkg_hash_to_file(nil)
+
+        if trace then
+            @log.info "Installed \"#{pkg_name} [#{pkg_ver}]\" package with all dependent packages.. OK"
+            @log.info "  [#{dependent_pkg_list.join(" -> ")}]"
+        else
+            @log.info "Install only \"#{pkg_name} [#{pkg_ver}]\" package.. OK"
+        end
+        return true
+       end
+
+    public
+    # install local package (ignore dependent packages)
+    def install_local_pkg(pkg_path, force)
+
+        file_name = File.basename(pkg_path)
+        pkg_name = file_name.split('_')[0]
+
+        if not File.exist? pkg_path then
+            @log.error "\"#{pkg_path}\" file does not exist"
+            return false
+        end
+        filename = File.basename(pkg_path)
+        ext = File.extname(filename)
+        if not ext.eql? ".zip" then
+            @log.error "\"#{file_name}\" is not zip file. binary package file should have .zip ext"
+            return false
+        end
+        pkg_name = filename.split("_")[0]
+        type = "binary"
+        manifest_file = "pkginfo.manifest"
+        pkg_config_path = File.join(@location, PACKAGE_INFO_DIR, pkg_name)
+
+        uniq_name = Utils.create_uniq_name
+        path = Utils::HOME + "/tmp/#{uniq_name}"
+        FileUtils.mkdir_p "#{path}"
+        if not FileInstaller.extract_specified_file(pkg_path, manifest_file, path) then
+            @log.error "pkginfo.manifest file does not exist in #{pkg_path}"
+            return false
+        end
+        manifest_path = File.join(path, manifest_file)
+        pkg_hash = Parser.read_pkg_list(manifest_path)
+        new_pkg_ver = pkg_hash[pkg_name].version
+        FileUtils.rm_f(manifest_path)
+        FileUtils.remove_dir(path, true)
+
+        compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+        if not force then
+            case compare_result
+            when -1 then
+                @log.warn "\"#{pkg_name}\" package version is bigger then remote package version.."
+                return true
+            when 0 then
+                @log.warn "\"#{pkg_name}\" package version is same with remote package version.."
+                return true
+            when 1, 2 then
+            end
+        end
+
+        if check_installed_pkg(pkg_name) then
+            uninstall(pkg_name, false)
+        end
+
+        # install package
+        ret = FileInstaller.install(pkg_name, pkg_path, "binary", @location)
+
+        add_local_pkg_info(pkg_name)
+        write_pkg_hash_to_file(nil)
+
+        @log.info "Installed \"#{pkg_path} [#{new_pkg_ver}]\" file.. OK"
+        return true
+    end
+
+    public
+    # upgrade package
+    def upgrade(os, trace)
+
+        if trace.nil? then trace = true end
+        list = check_upgrade(os)
+
+        if list.empty? or list.nil? then
+            @log.info "There is no packages for upgrading.."
+            return false
+        end
+
+        list.each do |p|
+            if check_installed_pkg(p) then
+                if not uninstall(p, trace) then
+                    @log.error "Failed to uninstall \"#{p}\" package.."
+                    return false
+                end
+            end
+
+            if not install(p, os, trace, false) then
+                @log.error "Failed to install \"#{p}\" package.."
+                return false
+            end
+        end
+
+        @log.info "Upgraded packages from #{@server_addr}.. OK"
+        return true
+    end
+
+    public
+    # check package which will be upgraded
+    def check_upgrade(os)
+
+        update_pkgs = []
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        installed_pkg_hash = installed_pkg_hash_loc[installed_pkg_hash_key]
+        remote_pkg_hash = pkg_hash_os[os]
+        
+        if remote_pkg_hash.nil? then
+            @log.error "There is no remote package list for #{os}. please pkg-cli update"
+            return nil
+        end
+
+        if installed_pkg_hash.nil? then
+            @log.warn "There is no any installed package in \"#{@location}\""
+            return remote_pkg_hash.keys
+        end
+
+        arr_keys = installed_pkg_hash.keys
+        arr_keys.each do |k|
+            installed_ver = get_attr_from_installed_pkg(k, "version")
+            if not check_remote_pkg(k, os) then next end
+            remote_ver = get_attr_from_pkg(k, os, "version")
+            compare_result = compare_version_with_installed_pkg(k, remote_ver)
+            case compare_result
+            when -1 then next
+            when 0 then next
+            when 1 then 
+                @log.output "\"#{k}\" package : #{installed_ver} -> #{remote_ver}"
+                update_pkgs.push(k) 
+            end
+        end
+
+        @log.info "Checked packages for upgrading.. OK"
+        return update_pkgs    
+    end
+
+    public
+    def get_default_server_addr()
+        filepath = "#{CONFIG_PATH}/config"
+        server_addr = nil
+
+        if not File.exist? filepath then create_default_config(nil) end
+        if not File.exist? filepath then
+            @log.error "There is no default server address in #{filepath}"
+            return nil
+        end
+
+        File.open filepath, "r" do |f|
+            f.each_line do |l|
+                if l.strip.start_with? "DEFAULT_SERVER_ADDR :" then
+                    server_addr = l.split("DEFAULT_SERVER_ADDR :")[1].strip
+                break
+                else next end
+            end
+        end
+
+        if server_addr.nil? then create_default_config(DEFAULT_SERVER_ADDR) end
+        return server_addr
+    end
+
+    public
+    # get default path for installing
+    def get_default_inst_dir()
+        return Dir.pwd 
+    end
+
+    private
+    # create default config file (Utils::HOME/.build_tools/client/config)
+    def create_default_config(server_addr)
+        filepath = "#{CONFIG_PATH}/config"
+        if server_addr.nil? then server_addr = DEFAULT_SERVER_ADDR end
+
+        if File.exist? filepath then
+            FileUtils.rm_f(filepath)
+        end
+
+        if server_addr.strip.end_with? "/" then server_addr = server_addr.chop end
+        
+        File.open(filepath, "a+") do |file|
+            file.puts "DEFAULT_SERVER_ADDR : #{server_addr}"
+        end
+    end
+
+    public
+    # uninstall package
+    # trace : if true, uninstall all dependent packages
+    def uninstall(pkg_name, trace)
+
+        type = "binary"
+        pkg_list = []
+        pkg_hash = nil
+
+        if not check_installed_pkg(pkg_name) then
+            @log.error "\"#{pkg_name}\" package is not installed."
+            return false 
+        end
+
+        pkg_ver = get_attr_from_installed_pkg(pkg_name, "version")
+
+        if trace then
+            pkg_list = get_all_reverse_install_dependent_packages(pkg_name, true)
+            if pkg_list.nil? then
+                @log.error "Failed to get \"#{pkg_name}\" package dependency information."
+                return false
+            end
+        else
+            pkg_list.push(pkg_name)
+        end
+
+        pkg_list.each do |p|
+            if not check_installed_pkg(p) then next end
+            if not FileInstaller.uninstall(p, type, @location) then
+                @log.error "Failed uninstall \"#{pkg_name}\" package"
+                return false
+            end
+            pkg_hash = remove_pkg_info(p)
+        end
+
+        if trace then
+            @log.info "Uninstalled \"#{pkg_name} [#{pkg_ver}]\" package with all dependent packages.. OK"
+            @log.info "  [#{pkg_list.join(" -> ")}]"
+        else
+            @log.info "Uninstalled only \"#{pkg_name} [#{pkg_ver}]\" package.. OK"
+        end
+
+        write_pkg_hash_to_file(nil)
+        return true
+    end
+
+    public 
+    # clean
+    def clean(force)
+        if not force then
+            puts "Do you really want to remove \"#{@location}\" path? [yes]"
+            input = $stdin.gets.strip
+            if input.upcase.eql? "YES" then
+                @log.info "Removed \"#{@location}\""
+            else
+                @log.info "Canceled"
+                return
+            end
+        end
+        FileUtils.rm_rf(@location)
+        FileUtils.mkdir_p(@location)
+        @pkg_hash_os.clear
+        @installed_pkg_hash_loc.clear
+        @archive_pkg_list.clear
+        @log.info "Cleaned \"#{@location}\" path.. OK"
+    end
+
+    public
+       # get reverse build dependent packages (just 1 depth)
+    def get_reverse_build_dependent_packages(pkg_name, os)
+
+        result = []
+        pkg_hash = @pkg_hash_os[os]
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.build_dep_list.each do |dep|
+                if dep.package_name.eql? pkg_name and
+                                       not dep.target_os_list.nil? and 
+                                       dep.target_os_list.include? os then
+                    result.push(pkg.package_name)
+                end
+            end
+        end
+
+        return result
+    end
+
+    public
+       # get reverse source dependent packages (just 1 depth)
+    def get_reverse_source_dependent_packages(pkg_name, os)
+
+        result = []
+        pkg_hash = @pkg_hash_os[os]
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.source_dep_list.each do |p|
+                if p.package_name.eql? pkg_name then
+                    result.push(pkg.package_name)
+                end
+            end
+        end
+
+        return result
+    end
+
+    public
+       # get reverse install dependent packages (jush 1 depth)
+    def get_reverse_install_dependent_packages(pkg_name, os)
+
+        result = []
+        pkg_hash = @pkg_hash_os[os]
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.install_dep_list.each do |p|
+                if p.package_name.eql? pkg_name then
+                    result.push(pkg.package_name)
+                end
+            end
+        end
+
+        return result
+    end
+
+    public
+       # get all build dependent packages (considered build priority, and reverse)
+    def get_build_dependent_packages(pkg_name, os, reverse)
+
+        if not check_remote_pkg(pkg_name, os) then return nil end
+        if reverse.nil? then reverse = true end
+
+        @all_dep_list.clear
+        begin            
+            get_build_dependency_arr(pkg_name, os, 0)
+        # in case of cross build dependency
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+
+        max = 0
+        @all_dep_list.each do |p|
+            if p[0].to_i > max then
+                max = p[0].to_i
+            else next end
+        end
+
+        result = []
+        i = 0
+        while i <= max
+            @all_dep_list.each do |p|
+                if p[0].to_i.eql? i then
+                    d = p[1]
+                    remote_os = get_attr_from_pkg(d.package_name, os, "os")
+                    remote_ver = get_attr_from_pkg(d.package_name, os, "version") 
+                    if not d.target_os_list.include? remote_os then
+                        @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.target_os_list.to_s}, but \"#{d.package_name}\" (#{remote_os}) package is in server"
+                        return nil
+                    end
+                    if not d.match? remote_ver then
+                        @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.comp} #{d.base_version}, but \"#{d.package_name}\" (#{remote_ver}) package is in server"
+                        return nil
+                    else result.push(d.package_name) end
+                end
+            end
+            i = i + 1
+        end
+
+        @log.info "Get build dependent packages for #{pkg_name} package.. OK"
+        if reverse then return result.reverse.uniq.push(pkg_name)
+        else return result.uniq.insert(0, pkg_name) end
+    end
+
+    public
+       # get all install dependent packages (considered install priority, reverse, and force)
+    # reverse : return reverse result
+    # force : install package force
+    def get_install_dependent_packages(pkg_name, os, reverse, force)
+
+        if not check_remote_pkg(pkg_name, os) then return nil end
+        if reverse.nil? then reverse = true end
+
+        @all_dep_list.clear
+        begin            
+            get_install_dependency_arr(pkg_name, os, force, 0)
+        # in case of cross build dependency
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+
+        max = 0
+        @all_dep_list.each do |p|
+            if p[0].to_i > max then
+                max = p[0].to_i
+            else next end
+        end
+
+        result = []
+        i = 0
+        while i <= max
+            @all_dep_list.each do |p|
+                if p[0].to_i.eql? i then
+                    d = p[1]
+                    remote_ver = get_attr_from_pkg(d.package_name, os, "version") 
+                    if not d.match? remote_ver then
+                        @log.error "\"#{pkg_name}\" package needs \"#{d.package_name}\" #{d.comp} #{d.base_version}, but \"#{d.package_name}\" (#{remote_ver}) package is in server"
+                        return nil
+                    else result.push(d.package_name) end
+                end
+            end
+            i = i + 1
+        end
+        
+        @log.info "Get install dependent packages for #{pkg_name} package.. OK"
+        if reverse then return result.reverse.uniq.push(pkg_name)
+        else return result.uniq.insert(0, pkg_name) end
+    end
+
+    public
+    # get all reverse install dependent packages (considered reverse install priority for tracing uninstall)
+    def get_all_reverse_install_dependent_packages(pkg_name, reverse)
+
+        if not check_installed_pkg(pkg_name) then return nil end
+        if reverse.nil? then reverse = true end
+
+        begin
+            res = get_all_reverse_install_dependency_arr(pkg_name, 0)
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+        res2 = res.split("::")
+        result = []
+        res2.each do |r|
+            result.push(r.split(':')[1])
+        end
+
+        @log.info "Get all reverse install dependent packages for #{pkg_name} package.. OK"
+        if reverse then return result.reverse.uniq
+        else return result end
+    end
+
+    public
+    # get all reverse remote dependent packages (considered reverse install priority for tracing uninstall)
+    def get_all_reverse_install_dependent_packages_remote(pkg_name, os, reverse)
+        #if not check_remote_pkg(pkg_name, os) then return nil end
+        if reverse.nil? then reverse = true end
+
+        begin
+            res = get_all_reverse_install_dependency_arr_remote(pkg_name, os, 0)
+        rescue SystemStackError
+            @log.error "Failed to get dependency relation because #{pkg_name} package has cross install dependency."
+            return nil
+        end
+        res2 = res.split("::")
+        result = []
+        res2.each do |r|
+            result.push(r.split(':')[1])
+        end
+
+        @log.info "Get all reverse install dependent packages for #{pkg_name} package.. OK"
+        if reverse then return result.reverse
+        else return result end
+    end
+
+    public
+    # check package whether to exist in remote server
+    def check_remote_pkg(pkg_name, os)
+
+        pkg_hash = @pkg_hash_os[os]
+        if pkg_hash.nil? then return false end
+        pkg = pkg_hash[pkg_name]
+        if pkg.nil? then
+            @log.warn "There is no \"#{pkg_name}\" remote package information in list"
+            return false
+        end
+
+        return true
+    end
+
+    public
+    # check package whether to exist in installed packages
+    def check_installed_pkg(pkg_name)
+
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+        if pkg_hash.nil? then return false end
+        pkg = pkg_hash[pkg_name]
+
+        if pkg.nil? then return false end
+        return true
+    end
+
+    public
+    # get attribute from installed package
+    def get_attr_from_installed_pkg(pkg_name, attr)
+
+        if not check_installed_pkg(pkg_name) then return nil end
+        pkg = get_installed_pkg_from_list(pkg_name)
+
+        if pkg.nil? then return nil end
+
+        case attr
+        when "version" then return pkg.version
+        when "source" then return pkg.source
+        when "src_path" then return pkg.src_path
+        when "os" then return pkg.os
+        when "build_dep_list" then return pkg.build_dep_list
+        when "install_dep_list" then return pkg.install_dep_list
+        when "attribute" then return pkg.attribute
+        end
+    end
+
+    public
+    # get attribute from remote package
+    def get_attr_from_pkg(pkg_name, os, attr)
+
+        if not check_remote_pkg(pkg_name, os) then return nil end
+        pkg = get_pkg_from_list(pkg_name, os)
+
+        if pkg.nil? then return nil end
+
+        case attr
+        when "path" then return pkg.path
+        when "source" then return pkg.source
+        when "version" then return pkg.version
+        when "src_path" then return pkg.src_path
+        when "os" then return pkg.os
+        when "build_dep_list" then return pkg.build_dep_list
+        when "install_dep_list" then return pkg.install_dep_list
+        when "attribute" then return pkg.attribute
+        end
+    end
+
+    public
+    # show a package information
+    def show_pkg_info(pkg_name, os)
+        if not check_remote_pkg(pkg_name, os) then
+            @log.error "\"#{pkg_name}\" package does not exist"
+            return ""
+        end
+
+        pkg = get_pkg_from_list(pkg_name, os)
+        return pkg.to_s
+    end
+
+    public
+    # show all packages information 
+    def show_pkg_list(os)
+        pkg_hash = @pkg_hash_os[os]
+        if pkg_hash.nil? then
+            @log.error "\"#{os}\" package list does not exist"
+            return ""
+        end
+
+        pkg_all_list = []
+        pkg_list = pkg_hash.values
+        pkg_list.each do |p|
+            pkg_all_list.push([p.package_name, p.version, p.description])
+        end
+        return pkg_all_list.sort
+    end
+
+    public
+    # show installed package information
+    def show_installed_pkg_info(pkg_name)
+
+        if not check_installed_pkg(pkg_name) then
+            @log.error "\"#{pkg_name}\" package does not exist"
+            return ""
+        end
+
+        pkg = get_installed_pkg_from_list(pkg_name)
+        return pkg.to_s
+    end
+
+    public
+    # show all installed packages information 
+    def show_installed_pkg_list()
+
+        file_path = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[file_path]
+        if pkg_hash.nil? then
+            @log.error "Installed package list does not exist"
+            return
+        end
+        pkg_all_list = [] 
+        pkg_list = pkg_hash.values
+        pkg_list.each do |p|
+            pkg_all_list.push([p.package_name, p.version, p.description])
+        end
+        return pkg_all_list.sort
+    end
+    
+    private
+    def get_build_dependency_arr(pkg_name, os, n)
+        pkg_hash = @pkg_hash_os[os]
+        pkg = pkg_hash[pkg_name]
+
+        if pkg.nil? then
+            @log.error "\"#{pkg_name}\" package does not exist in server. please check it"
+            return
+        end
+
+        # if package is already installed, skip tracing dependency
+        if check_installed_pkg(pkg_name) then
+            # compare version with installed package version
+            new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+            compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+            if compare_result == -1 or compare_result == 0 then return end
+        end
+
+        pkg.build_dep_list.each do |l|
+            @all_dep_list.push([n, l])
+            get_build_dependency_arr(l.package_name, os, n+1)
+        end
+    
+        return
+    end
+
+    private
+    def get_install_dependency_arr(pkg_name, os, force, n)
+
+        pkg_hash = @pkg_hash_os[os]
+        pkg = pkg_hash[pkg_name]
+
+        if pkg.nil? then
+            @log.error "\"#{pkg_name}\" package does not exist in server. please check it"
+            return
+        end
+    
+        # if package is already installed, skip tracing dependency
+        if check_installed_pkg(pkg_name) then
+            # compare version with installed package version
+            new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+            compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+            if not force then
+                if compare_result == -1 or compare_result == 0 then return end
+            end
+        end
+
+        pkg.install_dep_list.each do |l|
+            @all_dep_list.push([n, l])
+            get_install_dependency_arr(l.package_name, os, force, n+1)
+        end
+    
+        return 
+    end
+    
+    private
+    def get_all_reverse_install_dependency_arr(pkg_name, n)
+
+        s = "#{n}:#{pkg_name}"
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]                 
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.install_dep_list.each do |l|
+                if l.package_name.eql? pkg_name then
+                    s = s + "::" + get_all_reverse_install_dependency_arr(pkg.package_name, n+1)
+                end
+            end
+        end
+
+        return s
+    end
+
+    private
+    def get_all_reverse_install_dependency_arr_remote(pkg_name, os, n)
+
+        s = "#{n}:#{pkg_name}"
+        pkg_hash = @pkg_hash_os[os]                 
+        pkg_list = pkg_hash.values
+        pkg_list.each do |pkg|
+            pkg.install_dep_list.each do |l|
+                if l.package_name.eql? pkg_name then
+                    s = s + "::" + get_all_reverse_install_dependency_arr_remote(pkg.package_name, os, n+1)
+                end
+            end
+        end
+
+        return s
+    end
+
+    private 
+    def get_pkg_from_list(pkg_name, os)
+
+        pkg_hash = @pkg_hash_os[os]
+        if pkg_hash.nil? then return nil end
+        pkg = pkg_hash[pkg_name]
+        
+        return pkg
+    end
+
+    private
+    def get_installed_pkg_from_list(pkg_name)
+
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+        pkg = pkg_hash[pkg_name]
+        if pkg.nil? then return nil end
+
+        return pkg
+    end
+    
+    private
+    def install_pkg(pkg_name, os, force)
+
+        new_pkg_ver = ""
+        
+        # install remote server package file
+        if not check_remote_pkg(pkg_name, os) then
+            @log.error "\"#{pkg_name}\" package does not exist in remote server"
+            return false
+        end
+        path = get_attr_from_pkg(pkg_name, os, "path")
+        # type should be binary. type = "binary"
+        # below code should be changed
+        type = path.split('/')[-2]
+        new_pkg_ver = get_attr_from_pkg(pkg_name, os, "version")
+            
+        # compare version with installed package versiona
+        compare_result = compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+        if not force then
+            case compare_result
+            when -1 then
+               @log.warn "\"#{pkg_name}\" package version is bigger then remote package version"
+               return true
+            when 0 then
+               @log.warn "\"#{pkg_name}\" package version is same with remote package version"
+               return true
+            end
+        end
+        
+        if check_installed_pkg(pkg_name) then
+            uninstall(pkg_name, false)
+        end 
+
+        # download file
+        # change download location temporary (back to the origin path after downloading)
+        loc_back = @location
+        uniq_name = Utils.create_uniq_name
+        tmppath = Utils::HOME + "/tmp/#{uniq_name}"
+        FileUtils.mkdir_p "#{tmppath}"
+        @location = tmppath
+        file_local_path = download(pkg_name, os, false)[0]
+        @location = loc_back        
+        if file_local_path.nil? then return false end
+    
+        # install package
+        ret = FileInstaller.install(pkg_name, file_local_path, type, @location)
+        FileUtils.rm_f(file_local_path)
+        FileUtils.remove_dir(tmppath, true)
+        return ret
+    end
+
+    private
+    def compare_version_with_installed_pkg(pkg_name, new_pkg_ver)
+
+        if check_installed_pkg_list_file() then
+            create_installed_pkg_hash()
+            if check_installed_pkg(pkg_name) then
+                installed_pkg_ver = get_attr_from_installed_pkg(pkg_name, "version")
+                compare_result = Utils.compare_version(installed_pkg_ver, new_pkg_ver)
+                return compare_result
+            end
+        end
+
+        return 2
+    end
+
+    private
+    def remove_pkg_info(pkg_name)
+
+        pkg_hash = {}
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
+            pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]
+            if pkg_hash.include? pkg_name then
+                pkg_hash.delete(pkg_name)
+            end
+            @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+        else return nil end
+        
+        @log.info "Removed information for \"#{pkg_name}\" package.. OK"
+        return pkg_hash
+    end
+
+    private
+    def add_pkg_info(pkg_name, os)
+
+        pkg_hash = {}
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
+            pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]                
+            pkg_hash[pkg_name] = get_pkg_from_list(pkg_name, os)
+        else pkg_hash[pkg_name] = get_pkg_from_list(pkg_name, os) end
+        @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+
+        @log.info "Added information for \"#{pkg_name}\" package.. OK"
+        return pkg_hash
+    end
+
+    private
+    # add package manifest info
+    def add_local_pkg_info(pkg_name)
+        
+        config_path = File.join(@location, PACKAGE_INFO_DIR, "#{pkg_name}")
+        pkg = read_pkginfo_file(pkg_name, config_path)
+
+        if pkg.nil? then
+            @log.error "Failed to read pkginfo.manifest file"
+            return nil
+        end
+
+        pkg_hash = {} 
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then
+            pkg_hash = @installed_pkg_hash_loc[installed_pkg_hash_key]                
+            pkg_hash[pkg_name] = pkg
+        else pkg_hash[pkg_name] = pkg end
+        @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+
+        @log.info "Added information for \"#{pkg_name}\" package.. OK"
+        return pkg_hash
+    end
+
+    private
+    # read package manifet info
+    def read_pkginfo_file(pkg_name, path)
+
+        file_path = File.join(path, "pkginfo.manifest")
+        pkg_hash = Parser.read_pkg_list(file_path)
+
+        if pkg_hash.nil? then
+            @log.error "Failed to read manifest file : #{file_path}"
+            return nil
+        end
+
+        @log.info "Added information for \"#{pkg_name}\" package.. OK"
+        return pkg_hash[pkg_name]
+    end
+
+    private
+    # from_server : if true, update from server
+    def create_remote_pkg_hash(from_server)
+
+        for os in SUPPORTED_OS
+            filename = PKG_LIST_FILE_PREFIX + os
+            file_url = @server_addr + "/" + filename
+            local_file_path = File.join(CONFIG_PATH, filename)
+            if from_server then 
+                if not FileDownLoader.download(file_url, CONFIG_PATH) then
+                    return false
+                end
+            end
+            local_file_path = File.join(CONFIG_PATH, filename)
+            if File.exist? local_file_path then
+                pkg_hash = Parser.read_pkg_list(local_file_path)
+                @pkg_hash_os[os] = pkg_hash
+            end
+        end
+
+        filename = "archive_pkg_list"
+        file_url = @server_addr + "/" + filename
+        if from_server then 
+            if not FileDownLoader.download(file_url, CONFIG_PATH) then
+                @log.warn "Server does not have \"#{filename}\" file. This error can be ignored."
+            end
+        end
+        local_file_path = File.join(CONFIG_PATH, filename)
+        if File.exist? local_file_path then
+            File.open(local_file_path, "r") do |f|
+                f.each_line do |l|
+                    @archive_pkg_list.push(l.strip)
+                end
+            end
+        end
+
+        return true
+    end
+    
+    private
+    # create installed package hash
+    def create_installed_pkg_hash()
+
+        config_path = File.join(@location, PACKAGE_INFO_DIR)
+        if not File.directory? config_path then return end
+
+        installed_pkg_hash_key = get_installed_pkg_list_file_path()
+        if @installed_pkg_hash_loc.has_key? installed_pkg_hash_key then return
+        else      
+            file_path = installed_pkg_hash_key
+            if not File.exist? file_path then
+                #raise RuntimeError, "#{file_path} file does not exist"
+                return
+            end
+            pkg_hash = Parser.read_pkg_list(file_path)
+            @installed_pkg_hash_loc[installed_pkg_hash_key] = pkg_hash
+        end
+    end
+
+    private
+    # check to exist installed package list file
+    def check_installed_pkg_list_file()
+
+        if @location.nil? then raise RuntimeError, "#{@location} path does not exist" end
+        file_path = get_installed_pkg_list_file_path()
+        if File.exist? file_path then return true
+        else return false end
+    end
+
+    private
+    # get installed package list file path
+    def get_installed_pkg_list_file_path()
+
+        file_full_path = File.join(@location, PACKAGE_INFO_DIR, INSTALLED_PKG_LIST_FILE)        
+        return file_full_path
+    end
+
+    private
+    # write package hash to file
+    def write_pkg_hash_to_file(pkg_hash)
+
+        file_path = get_installed_pkg_list_file_path()
+        if pkg_hash.nil? then
+            pkg_hash = @installed_pkg_hash_loc[file_path]
+        end
+        if not pkg_hash.nil? then
+            config_path = File.join(@location, PACKAGE_INFO_DIR)
+            FileUtils.mkdir_p "#{config_path}"
+            if File.exist? file_path then File.delete(file_path) end
+            File.open(file_path, "a+") do |file|
+                file.puts "ORIGIN : #{@server_addr}"
+                file.puts "\n"
+                pkg_list = pkg_hash.values
+                pkg_list.each do |pkg|
+                    pkg.print_to_file(file)
+                    file.puts "\n"
+                end
+            end
+        end
+        @log.info "Write package informations to \"#{file_path}\".. OK"
+    end
+
+    private
+    def check_meta_pkg(pkg_name, os)
+        if not check_remote_pkg(pkg_name, os) then return false end
+
+        attr = get_attr_from_pkg(pkg_name, os, "attribute")
+        if attr.nil? or attr.empty? then return false end
+        if attr[0].strip.upcase.eql? "META" then return true
+        else return false end
+    end
+end
diff --git a/src/pkg_server/clientOptParser.rb b/src/pkg_server/clientOptParser.rb
new file mode 100644 (file)
index 0000000..ae12c36
--- /dev/null
@@ -0,0 +1,223 @@
+=begin
+ clientOptParser.rb
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'optparse'
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "utils"
+
+def set_default( options ) 
+       if options[:t].nil? then options[:t] = false end
+       if options[:f].nil? then options[:f] = false end
+       if options[:v].nil? then options[:v] = false end
+end
+
+def option_error_check( options )
+       $log.info "option error check"
+
+       case options[:cmd]
+
+    when "update" then
+
+    when "clean" then
+
+    when "upgrade" then
+
+    when "check-upgrade" then
+
+    when "download" then
+        if options[:pkg].nil? or options[:pkg].empty? then 
+                   raise ArgumentError, "Usage: pkg-cli download -p <pkg_name> [-o <os>] [-l <location>] [-u <package server url>] [-t]"
+        end
+
+    when "upload" then
+        if options[:alias].nil? or options[:alias].empty? or\
+                options[:id].nil? or options[:id].empty? or \
+                options[:srcpkg].nil? or options[:srcpkg].empty? then 
+                   raise ArgumentError, "Usage: pkg-cli upload -a <ssh_alias> -i <id> -s <source_package_path_list> [-b <binary_package_path_list>]"
+        end
+
+    when "source" then
+        if options[:pkg].nil? or options[:pkg].empty? then 
+                   raise ArgumentError, "Usage: pkg-cli source -p <pkg_name> [-o <os>] [-l <location>] [-u <package server url>]"
+        end
+
+    when "install" then
+        if options[:pkg].nil? or options[:pkg].empty? then 
+                   raise ArgumentError, "Usage: pkg-cli install -p <pkg_name> [-o <os>] [-l <location>] [-u <package server url>] [-t] [-f]"
+        end
+
+    when "install-file" then
+        if options[:pkg].nil? or options[:pkg].empty? then 
+                   raise ArgumentError, "Usage: pkg-cli install-lpkg -p <pkg_file> [-l <location>] [-f]"
+        end
+
+    when "uninstall" then
+        if options[:pkg].nil? or options[:pkg].empty? then 
+                   raise ArgumentError, "Usage: pkg-cli uninstall -p <pkg_name> [-l <location>] [-t]"
+        end
+
+    when "show-rpkg" then
+        if options[:pkg].nil? or options[:pkg].empty? then
+                   raise ArgumentError, "Usage: pkg-cli show-rpkg -p <pkg_name> [-o <os>] [-u <package server url>]"
+        end
+
+    when "list-rpkg" then
+
+    when "show-lpkg" then
+        if options[:pkg].nil? or options[:pkg].empty? then
+                   raise ArgumentError, "Usage: pkg-cli show-lpkg -p <pkg_name> [-l <location>]"
+        end
+
+    when "list-lpkg" then
+
+    when "build-dep" then
+        if options[:pkg].nil? or options[:pkg].empty? then
+                   raise ArgumentError, "Usage: pkg-cli build-dep -p <pkg_name> [-o <os>]"
+        end
+
+    when "install-dep" then
+        if options[:pkg].nil? or options[:pkg].empty? then
+                   raise ArgumentError, "Usage: pkg-cli install-dep -p <pkg_name> [-o <os>]"
+        end
+
+       else
+               raise ArgumentError, "input option incorrect : #{options[:cmd]}"
+       end
+end
+
+def option_parse 
+    options = {}
+    optparse = OptionParser.new do|opts|
+        # Set a banner, displayed at the top
+        # of the help screen.
+        opts.banner = "Usage: pkg-cli {update|clean|download|source|install|uninstall|upgrade|rpkg-show|rpkg-list|lpkg-show|lpkg-list|build-dep|install-dep|help} ..." + "\n" \
+        + "\t" + "pkg-cli update [-u <remote_server_url>]" + "\n" \
+        + "\t" + "pkg-cli clean [-l <location>] [-f]" + "\n" \
+        + "\t" + "pkg-cli download -p <pkg_name> [-o <os>] [-l <location>] [-u <package server url>] [-t]" + "\n" \
+        + "\t" + "pkg-cli upload -a <ssh_alias> -i <id> -s <source_package_path_list> [-b <binary_package_path_list]" + "\n" \
+        + "\t" + "pkg-cli source -p <pkg_name> [-o <os>] [-l <location>] [-u <package server url>]" + "\n" \
+        + "\t" + "pkg-cli install -p <pkg_name> [-o <os>] [-l <location>] [-u <package server url>] [-t] [-f]" + "\n" \
+        + "\t" + "pkg-cli install-file -p <pkg_file> [-l <location>] [-f]" + "\n" \
+        + "\t" + "pkg-cli uninstall -p <pkg_name> [-l <location>] [-t]" + "\n" \
+        + "\t" + "pkg-cli upgrade [-l <location>] [-o <os>] [-u <package server url>] [-t]" + "\n" \
+        + "\t" + "pkg-cli check-upgrade [-l <location>] [-o <os>] [-u <package server url>]" + "\n" \
+        + "\t" + "pkg-cli show-rpkg -p <pkg_name> [-o <os>] [-u <package server url>]" + "\n"  \
+        + "\t" + "pkg-cli list-rpkg [-o <os>] [-u <package server url>]" + "\n" \
+        + "\t" + "pkg-cli show-lpkg -p <pkg_name> [-l <location>]" + "\n"  \
+        + "\t" + "pkg-cli list-lpkg [-l <location>]" + "\n" \
+        + "\t" + "pkg-cli build-dep -p <pkg_name> [-o <os>]" + "\n"  \
+        + "\t" + "pkg-cli install-dep -p <pkg_name> [-o <os>]" + "\n"  \
+
+        opts.on( '-p', '--pkg <pkg_name or pkg_file>', 'package name or package file name' ) do |name|
+            options[:pkg] = name 
+        end
+        
+               opts.on( '-o', '--os <operating system>', 'target operating system' ) do |os|
+            options[:os] = os
+        end
+               
+               opts.on( '-u', '--url <server_address>', 'package server url' ) do|url|
+            options[:url] = url 
+        end
+
+               opts.on( '-a', '--alias <ssh_alias>', 'ssh alias' ) do|al|
+            options[:alias] = al
+        end
+
+               opts.on( '-i', '--id <id>', 'id' ) do|id|
+            options[:id] = id
+        end
+
+               opts.on( '-l', '--loc <location>', 'location' ) do |loc|
+            options[:loc] = loc
+        end
+
+               opts.on( '-s', '--src <source_package>', 'source package path' ) do|src|
+            options[:srcpkg] = []
+            list = src.tr(" \t","").split(",")
+            list.each do |l|
+                if l.start_with? "~" then l = Utils::HOME + l.delete("~") end
+                options[:srcpkg].push l
+            end
+        end
+
+               opts.on( '-t', '--trace', 'enable trace dependent packages' ) do
+            options[:t] = true
+        end
+
+               opts.on( '-b', '--bin <binary_package>', 'binary package path' ) do|bin|
+            options[:binpkg] = []
+            list = bin.tr(" \t","").split(",")
+            list.each do |l|
+                if l.start_with? "~" then l = Utils::HOME + l.delete("~") end
+                options[:binpkg].push l
+            end
+        end
+
+               opts.on( '-f', '--force', 'enable force' ) do
+            options[:f] = true
+        end
+               
+               opts.on( '-h', '--help', 'display this information' ) do
+            puts opts
+                       exit
+        end
+               
+    end
+    
+       $log.info "option parsing start" 
+    $log.info "option is : " + ARGV * "," 
+
+    cmd = ARGV[0] 
+    if cmd.eql? "update" or cmd.eql? "download" or \
+            cmd.eql? "install" or cmd.eql? "show-rpkg" or \
+            cmd.eql? "list-rpkg" or cmd.eql? "source" or \
+            cmd.eql? "uninstall" or cmd.eql? "show-lpkg" or \
+            cmd.eql? "list-lpkg" or cmd.eql? "upload" or \
+            cmd.eql? "install-file" or cmd.eql? "clean" or \
+            cmd.eql? "upgrade" or cmd.eql? "check-upgrade" or \
+            cmd.eql? "build-dep" or cmd.eql? "install-dep" or \
+            cmd =~ /(help)|(-h)|(--help)/  then
+        if cmd.eql? "help" then ARGV[0] = "-h" end
+        options[:cmd] = ARGV[0]
+    else
+        raise ArgumentError, "first paramter must be {update|clean|download|upload|source|install|install-file|uninstall|upgrade|check-upgrade|show-rpkg|list-rpkg|show-lpkg|list-lpkg|build-dep|install-dep|help} : your input is #{ARGV[0]}"
+    end
+
+    optparse.parse!
+   
+       $log.info "option parsing end" 
+
+       set_default options
+
+       # option error check 
+       option_error_check options
+
+    return options
+end 
+
diff --git a/src/pkg_server/distribution.rb b/src/pkg_server/distribution.rb
new file mode 100644 (file)
index 0000000..09f8da1
--- /dev/null
@@ -0,0 +1,497 @@
+=begin
+ distribution.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'fileutils'
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "parser"
+
+class Distribution 
+       attr_accessor :name, :location, :server_url
+
+    # constant
+    SUPPORTED_OS = ["linux", "windows", "darwin"]
+    PKG_LIST_FILE_PREFIX = "pkg_list_" 
+       ARCHIVE_PKG_LIST = "archive_pkg_list"
+
+       def initialize (name, location, server_url, log)
+
+               @name = name
+               @location = location
+               @pkg_hash_os = {}
+               @log = log
+               @server_url = server_url
+               @log.info "Distribution class[#{name}] initialize "
+
+        for os in SUPPORTED_OS 
+                       if @location.empty? or ( not File.exist? "#{@location}/#{PKG_LIST_FILE_PREFIX}#{os}" ) then
+                               @pkg_hash_os[os] = {}
+                       else 
+                               @pkg_hash_os[os] = Parser.read_pkg_list( "#{@location}/#{PKG_LIST_FILE_PREFIX}#{os}" )
+                       end
+               end
+       end
+
+       def register (file_path, pkg)
+               @log.info "Distribution class's register"
+               if pkg.nil? then
+                       raise RuntimeError, "package file does not contain pkginfo.manifest: [#{file_path}]"
+               end
+
+               exist_pkg = @pkg_hash_os[pkg.os][pkg.package_name]
+          
+               # version check and if existing version is higher then upload version?
+               if not exist_pkg.nil? 
+                       if not ( Utils.compare_version( exist_pkg.version, pkg.version ).eql? 1 ) then
+                               raise RuntimeError, "existing package's version is higher than register package"
+                       end
+               end
+
+               # modified pkg class
+               pkg.origin = "local" 
+        pkg.source = ""
+               pkg.path = "/binary/" + File.basename( file_path )
+               # TODO: windows and mac : sha256sum
+               if Utils::HOST_OS.eql? "linux" then
+                       pkg.checksum = `sha256sum #{file_path}`.split(" ")[0]
+               end 
+               pkg.size = `du -b #{file_path}`.split[0].strip
+
+               @pkg_hash_os[pkg.os][pkg.package_name] = pkg 
+               
+               return pkg
+       end
+
+       def register_for_test (file_path, pkg)
+               @log.info "Distribution class's register for test"
+               if pkg.nil? then
+                       raise RuntimeError, "package file does not contain pkginfo.manifest: [#{file_path}]"
+               end
+
+               # modified pkg class
+               pkg.origin = "local" 
+        pkg.source = ""
+               pkg.path = "/temp/" + File.basename( file_path )
+               # TODO: windows and mac : sha256sum
+               if Utils::HOST_OS.eql? "linux" then
+                       pkg.checksum = `sha256sum #{file_path}`.split(" ")[0]
+               end
+               pkg.size = `du -b #{file_path}`.split[0].strip
+
+               return pkg
+       end
+
+       def generate_snapshot (name, base_snapshot, append_pkg_list)
+               @log.info "Distribution class's generate snapshot"
+               # if name is nil or empty then create uniq name
+               if name.nil? or name.empty? then
+                       name = Utils.create_uniq_name
+               end
+
+               # check base snapshot exist 
+               if File.exist? "#{@location}/snapshots/#{name}" then 
+                       raise "Snapshot is already exist: #{name}"
+               end
+
+               if base_snapshot.nil? then base_snapshot = "" else base_snapshot.strip! end
+               if append_pkg_list.nil? then append_pkg_list = [] end 
+
+               if base_snapshot.empty? and append_pkg_list.empty? then 
+                       FileUtils.mkdir "#{@location}/snapshots/#{name}"
+
+               for os in SUPPORTED_OS 
+                               FileUtils.copy( "#{@location}/#{PKG_LIST_FILE_PREFIX}#{os}", 
+                                                          "#{@location}/snapshots/#{name}/#{PKG_LIST_FILE_PREFIX}#{os}" )
+                       end 
+
+                       # copy archive package list
+                       begin 
+                               FileUtils.copy( "#{@location}/#{ARCHIVE_PKG_LIST}", "#{@location}/snapshots/#{name}/#{ARCHIVE_PKG_LIST}" )
+                       rescue => e
+                               @log.warn "ARCHIVE_PKG_LIST not exist"  
+                       end
+
+
+                       @log.output( "snapshot is generated : #{@location}/snapshots/#{name}", Log::LV_USER)
+               # base_snapshot is exist 
+               elsif not ( base_snapshot.empty? ) then
+                       FileUtils.mkdir "#{@location}/snapshots/#{name}"
+                       
+               for os in SUPPORTED_OS 
+                               # check base snapshot exist 
+                               if (not File.exist? "#{@location}/snapshots/#{base_snapshot}/#{PKG_LIST_FILE_PREFIX}#{os}") then
+                                       raise RuntimeError, "Can't find base snapshot [#{base_snapshot}]"
+                               end 
+                               
+                               base_pkg_list = Parser.read_pkg_list( "#{@location}/snapshots/#{base_snapshot}/#{PKG_LIST_FILE_PREFIX}#{os}" )
+                               snapshot_generate2( name, os, base_pkg_list, append_pkg_list )
+                       end
+               
+                       # copy archive package list
+                       begin 
+                               FileUtils.copy( "#{@location}/#{ARCHIVE_PKG_LIST}", "#{@location}/snapshots/#{name}/#{ARCHIVE_PKG_LIST}" )
+                       rescue => e
+                               @log.warn "ARCHIVE_PKG_LIST not exist"  
+                       end
+
+                       @log.output( "snapshot is generated : #{@location}/snapshots/#{name}", Log::LV_USER)
+               # base_snapshot is empty
+               else 
+                       FileUtils.mkdir "#{@location}/snapshots/#{name}" 
+
+               for os in SUPPORTED_OS  
+                               base_pkg_list = Parser.read_pkg_list( "#{@location}/#{PKG_LIST_FILE_PREFIX}#{os}" )
+                               snapshot_generate2( name, os, base_pkg_list, append_pkg_list )
+                       end 
+
+                       # copy archive package list
+                       begin 
+                               FileUtils.copy( "#{@location}/#{ARCHIVE_PKG_LIST}", "#{@location}/snapshots/#{name}/#{ARCHIVE_PKG_LIST}" )
+                       rescue => e
+                               @log.warn "ARCHIVE_PKG_LIST not exist"  
+                       end
+
+                       @log.output( "snapshot is generated : #{@location}/snapshots/#{name}", Log::LV_USER)
+               end
+       end  
+
+       def snapshot_generate2( name, os, pkg_list, append_pkg_list )
+               @log.info "snapshot_generate2: input append_pkg_list #{append_pkg_list}"
+               append_pkg_list.each do |pkg| 
+                       # os check
+                       if pkg.os.eql? os.strip then pkg_list[pkg.package_name] = pkg end
+               end
+       
+               File.open( "#{@location}/snapshots/#{name}/#{PKG_LIST_FILE_PREFIX}#{os}", "w" ) do |f|
+                       pkg_list.each_value do |pkg|
+                               pkg.print_to_file(f)
+                               f.puts 
+                       end
+               end     
+       end
+
+       def sync( force, os ) 
+
+               # check distribution's server_url
+               if @server_url.empty? then 
+                       @log.error( "This distribution has not remote server"  , Log::LV_USER)
+                       return
+               end
+
+               # generate client class
+               client_bin = Client.new( @server_url, "#{@location}/binary", @log )
+               client_bin.update
+               client_src = Client.new( @server_url, "#{@location}/source", @log )
+               client_src.update
+           
+               source_pkg_path_list = []
+               dep_pkg_path_list = []
+
+               # error check 
+               if client_bin.pkg_hash_os[os].nil? then 
+                       raise "Package list can't generated. url is #{@server_url}. os is #{os}"
+               end 
+
+               # check existing source package list 
+               @pkg_hash_os[os].each_value do |pkg|
+                       if not source_pkg_path_list.include? pkg.src_path then 
+                               source_pkg_path_list.push pkg.src_path
+                       end
+               end 
+
+               full_pkg_list = client_bin.pkg_hash_os[os].merge(@pkg_hash_os[os])
+
+               full_pkg_list.each_key do |pkg_name|
+                       server_pkg = client_bin.pkg_hash_os[os][pkg_name]
+                       local_pkg = @pkg_hash_os[os][pkg_name] 
+
+                       # if server and local has package
+                       if ( not server_pkg.nil? ) and ( not local_pkg.nil? ) then
+                               # if server version is not updated then skip
+                               if not ( Utils.compare_version( local_pkg.version, server_pkg.version ).eql? 1 ) then 
+                                       @log.info "existing packages version equal or higher then server's version so package[#{pkg_name}] skip"
+                                       @log.info "server package version: [#{server_pkg.version}]"
+                                       @log.info "local package version: [#{local_pkg.version}]" 
+                                       
+                                       next
+                               end 
+
+                               # if server version is not updated then skip
+                               # if server's pakcage is local package and mode is not force then local package will be upaded 
+                               if ( local_pkg.origin.eql? "local" ) and ( not force ) then
+                                       @log.info "package [#{pkg_name}] is local package. so skip update"
+                                       
+                                       next
+                               end 
+
+                               # package update
+                               @log.info "update package from server: [#{pkg_name}]"
+                               file_path_list = client_bin.download( pkg_name, os, false )
+                               
+                               # file download error check 
+                               if file_path_list.nil? or file_path_list.empty? then   
+                                       @log.error( "Can't download package file #{pkg_name}" , Log::LV_USER)
+                                       next
+                               else
+                                       @log.info "download binary package successfully: [#{pkg_name}]"
+                                       file_path = file_path_list[0]
+                               end 
+                
+                               # update pkg class  
+                               server_pkg.path = "/binary/#{File.basename(file_path)}"
+                               server_pkg.origin = client_bin.server_addr
+                               @pkg_hash_os[os][pkg_name] = server_pkg 
+
+                               dep_pkg_path_list = dep_pkg_path_list +  server_pkg.source_dep_list
+
+                                # if binary only package, then skip downloading its source
+                               if server_pkg.src_path.empty? then next end
+
+                                # if binary's source package is not downlaoded, download it
+                               if ( not source_pkg_path_list.include? server_pkg.src_path ) then
+                                       @log.info "download source package: [#{server_pkg.src_path}]"
+                                       file = client_src.download_source( pkg_name, os )
+                                       if file.nil? then  
+                                               @log.error "Can't download source package [#{pkg_name}]"
+                                       else
+                                               source_pkg_path_list.push server_pkg.src_path 
+                                       end 
+                               end
+                       # if package exist only server
+                       elsif ( not server_pkg.nil? ) then
+                               #downnlaod binary package
+                               file_path_list = client_bin.download( pkg_name, os, false )
+                
+                               # file download error check 
+                               if file_path_list.nil? or file_path_list.empty? then   
+                                       @log.error( "Can't download package file #{pkg_name}", Log::LV_USER) 
+                                       next
+                               else
+                                       @log.info "download binary package successfully: [#{pkg_name}]"
+                                       file_path = file_path_list[0]
+                               end 
+                
+                               # update pkg class
+                               server_pkg.path = "/binary/#{File.basename(file_path)}"
+                               server_pkg.origin = client_bin.server_addr
+                               @pkg_hash_os[os][pkg_name] = server_pkg
+                
+                               dep_pkg_path_list = dep_pkg_path_list +  server_pkg.source_dep_list 
+                
+                                # if binary only package, then skip downloading its source
+                               if server_pkg.src_path.empty? then next end
+                
+                                # if binary's source package is not downlaoded, download it
+                               if not source_pkg_path_list.include? server_pkg.src_path then
+                                       @log.info "download source package: [#{server_pkg.src_path}]"
+                                       file = client_src.download_source( pkg_name, os )
+                                       if file.nil? 
+                                               @log.error "Can't download source package [#{server_pkg.src_path}]"
+                                       else 
+                                               source_pkg_path_list.push server_pkg.src_path 
+                                       end
+                               end
+                       # if package exist only local
+                       elsif ( not local_pkg.nil? ) then  
+                               # if pakcage is not local package then server's package is removed 
+                               # so, local package remove
+                               if not local_pkg.origin.eql? "local" then  
+                                       @pkg_hash_os[os].delete(pkg_name)
+                               end
+                       else
+                               raise RuntimeError,"hash merge error!"
+                       end
+               end
+
+               @log.info "pkg file update end"
+               # download dependency source packages 
+               dep_pkg_path_list.uniq.each do |dep|
+                       if dep.package_name.strip.empty? then next end
+                       @log.info "download dep package: [#{dep.package_name}]"
+                       file = client_src.download_dep_source( dep.package_name )
+                       if file.nil? 
+                               @log.error "Can't download dep package [#{dep.package_name}]"
+                       end 
+               end 
+
+               @log.info "pkg deb file update end"
+               # pakcage list file update
+               write_pkg_list(os)
+               @log.info "write pkg list"
+       end
+
+       def sync_archive_pkg
+               client = Client.new( @server_url, "#{@location}/source", @log )
+               client.update 
+
+               downloaded_list = []
+               client.archive_pkg_list.each do |pkg| 
+                       if not File.exist? "#{@location}/source/#{pkg}" then
+                               file = client.download_dep_source(pkg) 
+                               if file.nil? 
+                                       @log.error "Can't download archive package [#{file}]"
+                               else 
+                                       downloaded_list.push pkg
+                               end
+                       end
+               end 
+
+               write_archive_pkg_list( downloaded_list )
+       end 
+
+       def write_pkg_list( os )
+               File.open( "#{@location}/#{PKG_LIST_FILE_PREFIX}#{os}", "w" ) do |f| 
+                       @pkg_hash_os[os].each_value do |pkg|
+                               pkg.print_to_file(f)
+                               f.puts 
+                       end
+               end     
+       end
+
+       def write_archive_pkg_list( pkg_file_name_list )
+               File.open( "#{@location}/#{ARCHIVE_PKG_LIST}", "a" ) do |f| 
+                       pkg_file_name_list.map { |name| f.puts(name) }
+               end     
+       end
+
+       # input: package file path(zip file) 
+       # return: pkg 
+       def get_package_from_file(file_path)
+               tmp_dir = "./" + Utils.create_uniq_name
+               FileUtils.mkdir "#{@location}/#{tmp_dir}"
+
+               # file extention is zip 
+               if file_path.end_with? ".zip" then
+                       system("unzip -q #{file_path} pkginfo.manifest -d #{@location}/#{tmp_dir} ")
+               # file extention is tar.gz
+               elsif file_path.end_with? ".tar.gz" or file_path.end_with? ".tar" then
+                       system("tar -xzf #{file_path} -C #{@location}/#{tmp_dir}")
+               else
+                       raise "unsupported zipping file. just use [zip/tar.gz]"
+               end
+               pkg = Parser.read_pkginfo( "#{@location}/#{tmp_dir}/pkginfo.manifest" )
+               FileUtils.rm_rf "#{@location}/#{tmp_dir}"
+
+               return pkg
+       end 
+
+       def remove_pkg( pkg_name_list )  
+               for package_name in pkg_name_list
+                       removed_flag = false 
+
+               for os in SUPPORTED_OS 
+                               if @pkg_hash_os[os].key?(package_name) then 
+                                       @log.info( "remove package [#{package_name}] in #{os}", Log::LV_USER)
+                                       @pkg_hash_os[os].delete(package_name)  
+                                       removed_flag = true
+                               end
+                       end  
+
+                       if not removed_flag then 
+                               @log.error( "Can't find package: #{package_name}", Log::LV_USER)
+                       end
+               end 
+
+               # check install dependency integrity
+               check_instll_dependency_integrity 
+
+        for os in SUPPORTED_OS 
+                       write_pkg_list(os) 
+               end
+       end 
+
+       def check_instll_dependency_integrity 
+               @log.info "check server pkg's install dependency integrity" 
+
+               for os in SUPPORTED_OS 
+                       for pkg in @pkg_hash_os[os].each_value 
+                               error_msg = "[#{pkg.package_name}]'s install dependency not matched in "  
+
+                               for dep in pkg.install_dep_list  
+                                       if @pkg_hash_os[os].has_key? dep.package_name then   
+                                               target_pkg = @pkg_hash_os[os][dep.package_name]
+                                       else 
+                                               raise RuntimeError,(error_msg + dep.to_s) 
+                                       end
+                               
+                                       # TODO: check just install dependency exist
+                                       next 
+                                       
+                                       # check package's version 
+                                       if not dep.match? target_pkg.version then 
+                                               raise RuntimeError,(error_msg + dep.to_s)
+                                       end 
+
+                                       # TODO: install dependency's os is always ture
+                                       #if not dep.target_os_list.length == 0 then 
+                                       #       if not dep.target_os_list.include? target_pkg.os then  
+                                       #               raise RuntimeError,(error_msg + dep.to_s)
+                                       #       end 
+                                       #end 
+                               end 
+
+                               # TODO: check just install dependency 
+                               next 
+
+                               error_msg = "[#{pkg.package_name}]'s build dependency not matched in "  
+                               for dep in pkg.build_dep_list 
+                                       if dep.target_os_list.length == 0 then
+                                               build_dep_os = os  
+                                       else
+                                               build_dep_os = dep.target_os_list[0]
+                                       end
+
+                                       if @pkg_hash_os[build_dep_os].has_key? dep.package_name then   
+                                               target_pkg = @pkg_hash_os[build_dep_os][dep.package_name]
+                                       else 
+                                               raise RuntimeError,(error_msg + dep.to_s) 
+                                       end
+                                       
+                                       # check package's version 
+                                       if not dep.match? target_pkg.version then 
+                                               raise RuntimeError,(error_msg + dep.to_s)
+                                       end 
+
+                                       # TODO: check package's target_os   
+                                       #if not dep.target_os_list.length == 0 then 
+                                       #       if not dep.target_os_list.include? target_pkg.os then  
+                                       #               raise RuntimeError,(error_msg + dep.to_s)
+                                       #       end 
+                                       #end 
+                               end 
+
+                               error_msg = "[#{pkg.package_name}]'s source dependency not matched in "  
+                               for dep in pkg.source_dep_list 
+                                       # check source package exist
+                                       if not File.exist? "#{@location}/source/#{dep.package_name}"
+                                               raise RuntimeError,(error_msg + dep.to_s)
+                                       end 
+                               end 
+                       end
+               end 
+       end
+end
diff --git a/src/pkg_server/downloader.rb b/src/pkg_server/downloader.rb
new file mode 100644 (file)
index 0000000..0308208
--- /dev/null
@@ -0,0 +1,68 @@
+=begin
+ downloader.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "utils"
+
+class FileDownLoader
+
+    @@log = nil
+
+    def FileDownLoader.set_logger(logger)
+        @@log = logger
+    end
+
+    def FileDownLoader.download(url, path)
+        ret = false
+
+        if not File.directory? path then
+            @@log.error "\"#{path}\" does not exist"
+            return ret
+        end
+        
+        is_remote = Utils.is_url_remote(url)
+        filename = url.split('/')[-1]
+
+        fullpath = File.join(path, filename)
+
+        if is_remote then
+            ret = system "wget #{url} -O #{fullpath} -nv"
+        else
+            if not File.exist? url then
+                @@log.error "\"#{url}\" file does not exist"
+                return false
+            else
+                ret = system "cp #{url} #{fullpath}"
+            end
+        end
+
+        # need verify
+        return ret
+    end
+end
+
diff --git a/src/pkg_server/installer.rb b/src/pkg_server/installer.rb
new file mode 100644 (file)
index 0000000..0006b8d
--- /dev/null
@@ -0,0 +1,300 @@
+=begin
+ installer.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "serverConfig"
+require "log"
+require "utils"
+
+class FileInstaller
+
+    CONFIG_PATH = "#{$build_tools}/client"
+    PACKAGE_INFO_DIR = ".info"
+
+    @@log = nil
+
+    def FileInstaller.set_logger(logger)
+        @@log = logger
+    end
+
+    def FileInstaller.install(package_name, package_file_path, type, target_path)
+
+        if not File.exist? package_file_path then
+            @@log.error "\"#{package_file_path}\" file does not exist."
+            return false
+        end
+
+        case type
+        # install script when binary package
+        when "binary" then
+            uniq_name = Utils.create_uniq_name
+            path = Utils::HOME + "/tmp/#{uniq_name}"
+            if Utils::HOST_OS.eql? "windows" then
+                drive = Utils::HOME.split("/")[0]
+                path = "#{drive}/#{uniq_name}"
+            end
+            FileUtils.mkdir_p "#{path}"
+
+            if File.directory? path then
+               log = "##### create temporary dir : #{path} #####\n"
+            else
+               log = "##### [Failed] create temporary dir : #{path} #####\n"
+               return false 
+            end
+
+            log = log + "##### extract file : #{package_file_path} #####\n"
+            log = log + extract_file(package_name, package_file_path, path, target_path)
+            move_dir(package_name, path, target_path)
+
+            log = log + "##### execute install script #####\n"
+            log = log + execute_install_script(package_name, path, target_path)
+
+            log = log + "##### move remove script #####\n"
+            move_remove_script(package_name, path, target_path)
+
+            log = log + "##### remove temporary dir : #{path} #####\n"
+            Utils.execute_shell("rm -rf #{path}")
+
+            target_config_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
+            FileUtils.mkdir_p(target_config_path)
+            pkg_inst_log = "#{package_name}_inst.log"
+            pkg_inst_log_path = File.join(target_config_path, pkg_inst_log)
+
+            File.open(pkg_inst_log_path, "a+") do |f|
+                f.puts log
+            end
+
+        when "source" then
+        end
+
+        # need verify
+        return true;
+    end
+
+    def FileInstaller.move_remove_script(package_name, path, target_path)
+        target_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
+        FileUtils.mkdir_p(target_path)
+        script_file_prefix = "#{path}/remove.*"
+        script_file = Dir.glob(script_file_prefix)[0]
+
+        if not script_file.nil? then
+            FileUtils.mv(script_file, target_path)
+        end
+    end 
+
+
+    def FileInstaller.execute_install_script(package_name, path, target_path)
+        script_file_prefix = "#{path}/install.*"
+        script_file = Dir.glob(script_file_prefix)[0]
+        log = ""
+        
+        if not script_file.nil? then
+            @@log.info "Execute \"#{script_file}\" file"
+            cmd = "set INSTALLED_PATH=\"#{target_path}\"& #{script_file}"
+            log = `#{cmd}`
+        end
+        return log
+    end
+
+    def FileInstaller.execute_remove_script(package_name, target_path)
+        info_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
+        if not File.directory? info_path then
+            return false
+        end
+
+        script_file_prefix = "#{info_path}/remove.*"
+        script_file = Dir.glob(script_file_prefix)[0]
+        log = ""
+
+        if not script_file.nil? then
+            @@log.info "Execute \"#{script_file}\" file"
+            cmd = "set INSTALLED_PATH=\"#{target_path}\"& #{script_file}"
+            log = `#{cmd}`
+        end
+    end
+
+    def FileInstaller.remove_pkg_files(package_name, target_path)
+        list_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
+
+        if not File.directory? list_path then
+            return false
+        end
+
+        list_file_name = "#{list_path}/#{package_name}.list"
+        list_file = Dir.glob(list_file_name)[0]
+        directories = []
+
+        if not list_file.nil? then
+            File.open(list_file, "r") do |file|
+                file.each_line do |f|
+                    f = f.strip
+                    if f.nil? or f.empty? then next end
+                    file_path = File.join(target_path, f)
+                    if File.directory? file_path then
+                        if File.symlink? file_path then 
+                            File.unlink file_path
+                            next
+                        end
+                        entries = Dir.entries(file_path)
+                        if entries.include? "." then entries.delete(".") end
+                        if entries.include? ".." then entries.delete("..") end
+                        if entries.empty? or entries.nil? then
+                            begin
+                                Dir.rmdir(file_path)
+                            rescue SystemCallError
+                                @@log.warn "\"#{file_path}\" directory is not empty"
+                            end 
+                        else directories.push(file_path) end
+                    elsif File.file? file_path then FileUtils.rm_f(file_path)
+                    elsif File.symlink? file_path then File.unlink file_path 
+                    # if files are already removed by remove script,
+                    else @@log.warn "\"#{file_path}\" does not exist" end
+                end
+            end
+
+            directories.reverse.each do |path|
+                entries = Dir.entries(path)
+                if entries.include? "." then entries.delete(".") end
+                if entries.include? ".." then entries.delete("..") end
+                if entries.empty? or entries.nil? then
+                begin
+                    Dir.rmdir(path)
+                rescue SystemCallError
+                    @@log.warn "\"#{file_path}\" directory is not empty"
+                end 
+                else next end
+           end
+        end
+        #FileUtils.rm_rf(list_path)
+        Utils.execute_shell("rm -rf #{list_path}")
+        return true
+    end
+
+    def FileInstaller.uninstall(package_name, type, target_path)
+        case type
+        when "binary" then
+            execute_remove_script(package_name, target_path)
+            remove_pkg_files(package_name, target_path)
+        when "source" then
+        end
+
+        return true
+    end
+
+    def FileInstaller.move_dir(package_name, source_path, target_path)
+        config_path = File.join(target_path, PACKAGE_INFO_DIR, package_name)
+        FileUtils.cp_r Dir.glob("#{source_path}/data/*"), target_path
+        FileUtils.cp "#{source_path}/pkginfo.manifest", config_path
+    end
+
+    def FileInstaller.extract_file(package_name, package_file_path, path, target_path)
+        dirname = File.dirname(package_file_path)
+        filename = File.basename(package_file_path)
+        ext = File.extname(filename)
+
+        target_config_path = target_path + "/#{PACKAGE_INFO_DIR}/#{package_name}"
+        FileUtils.mkdir_p(target_config_path)
+        pkg_file_list = "#{package_name}.list"
+        pkg_file_list_path = File.join(target_config_path, pkg_file_list)
+        temp_pkg_file_list = "temp_file_list"
+        temp_pkg_file_list_path = File.join(target_config_path, "temp_file_list")
+
+        show_file_list_command = nil
+        extrach_file_list_command = nil
+
+        case ext
+        when ".zip" then
+            show_file_list_command = "zip -sf #{package_file_path}"
+            extract_file_list_command = "unzip \"#{package_file_path}\" -d \"#{path}\""
+        when ".tar" then
+            show_file_list_command = "tar -sf #{package_file_path}"
+            extract_file_list_command = "tar xf \"#{package_file_path}\" -C \"#{path}\""
+        else
+            @@log.error "\"#{filename}\" is not supported."
+            return nil 
+        end
+
+        system "#{show_file_list_command} > #{temp_pkg_file_list_path}"
+        File.open(pkg_file_list_path, "a+") do |targetfile|
+            File.open(temp_pkg_file_list_path, "r") do |sourcefile|
+                sourcefile.each_line do |l|
+                    if l.strip.start_with? "data/" then
+                        ml = l.strip[5..-1]
+                        targetfile.puts ml
+                    else next end
+                end
+            end
+        end
+
+        File.delete(temp_pkg_file_list_path)
+        log = `#{extract_file_list_command}`
+        @@log.info "Extracted \"#{filename}\" file.."
+        if log.nil? then log = "" end
+        return log
+    end
+
+    def FileInstaller.extract_specified_file(package_file_path, target_file, path)
+        dirname = File.dirname(package_file_path)
+        filename = File.basename(package_file_path)
+        ext = File.extname(filename)
+        
+        case ext
+        when ".zip" then
+            if not path.nil? then
+                extract_file_command = "unzip -x #{package_file_path} #{target_file} -d #{path}"
+            else
+                extract_file_command = "unzip -x #{package_file_path} #{target_file}"
+            end
+        when ".tar" then
+            if not path.nil? then
+                path = File.join(path, package_file_path)
+                extract_file_command = "tar xvf #{package_file_path} #{target_file}"
+            else
+                extract_file_command = "tar xvf #{package_file_path} #{target_file}"
+            end
+        end
+
+        system "#{extract_file_command}"
+        
+        if not path.nil? then
+            target_file_path = File.join(path, target_file)
+        else
+            target_file_path = target_file
+        end
+
+        if File.exist? target_file_path then
+            @@log.info "Extracted \"#{target_file}\" file.."
+            return true
+        else
+            @@log.info "Failed to extracted \"#{target_file}\" file.."
+            return false
+        end
+    end
+end
+
diff --git a/src/pkg_server/packageServer.rb b/src/pkg_server/packageServer.rb
new file mode 100644 (file)
index 0000000..dce1b6b
--- /dev/null
@@ -0,0 +1,526 @@
+=begin
+ packageServer.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'fileutils'
+$LOAD_PATH.unshift File.dirname(__FILE__)
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "packageServerLog"
+require "serverConfig"
+require "distribution"
+require "client"
+require "utils"
+require "mail"
+
+class PackageServer
+       attr_accessor :id, :location
+    
+       # constant
+    SUPPORTED_OS = ["linux", "windows", "darwin"]
+
+       # initialize
+       def initialize (id)
+               @id = id
+               @location = ""
+               @distribution_list = []
+               # distribution name -> server_url hash
+               @dist_to_server_url = {}
+
+               if not File.exist? $server_root then
+                       FileUtils.mkdir_p( $server_root )
+               end
+               @log = PackageServerLog.new( "#{$server_root}/.#{@id}.log", $stdout) 
+
+               server_information_initialize()
+               set_distribution_list()
+       end
+
+       # create
+       def create (id, dist_name, server_url, loc = nil )
+               @id = id 
+               if loc.nil? or loc.empty? then
+                       @location = Dir.pwd + "/" + id 
+               else
+                       if loc.end_with? "/" then  
+                               @location = loc + id 
+                       else 
+                               @location = loc + "/" + id 
+                       end
+               end
+
+               # create locking file
+               File.open("#{$server_create_loc_file}", File::RDWR|File::CREAT, 0644) {|f|
+                       f.flock(File::LOCK_EX)
+                       f.rewind
+                       f.flush
+                       f.truncate(f.pos)
+
+                       # error check : check for already exist in server id 
+                       if File.exist? "#{$server_root}/#{id}" 
+                               raise RuntimeError, "Server create fail. server id [#{id}] is already exist"
+                       end
+                       
+                       # error check : check for already exist in server directory 
+                       if File.exist? "#{@location}/#{dist_name}"
+                               raise RuntimeError, "Server create fail. directory is already exist [#{@location}/#{dist_name}]" 
+                       end
+    
+                       # create server config directory
+                       FileUtils.mkdir_p "#{$server_root}/#{id}"
+                       FileUtils.mkdir_p "#{$server_root}/#{id}/incoming"
+
+                       if (not server_url.empty?) and (not Utils.is_url_remote(server_url))
+                               # if server_url is local server address then generate absoulte path 
+                               if not Utils.is_absolute_path( server_url ) then 
+                                       if server_url.end_with?("/") then
+                                               server_url = Utils::WORKING_DIR + server_url 
+                                       else
+                                               server_url = Utils::WORKING_DIR + "/" + server_url 
+                                       end
+                               end
+                       end 
+
+                       # create server configure file
+                       File.open( "#{$server_root}/#{id}/config", "w" ) do |f|
+                               f.puts "location : #{@location}"
+                               f.puts "server_url : #{dist_name} ->  #{server_url}"
+                       end
+                       
+                       # create location's directory
+                       FileUtils.mkdir_p "#{@location}"
+                       
+                       create_distribution_struct( dist_name, server_url )
+               }       
+       end
+
+       def register( source_pkg_file_path_list, binary_pkg_file_path_list, dist_name, snapshot, test )
+               @log.info "package register in server"
+               if dist_name.empty? then dist_name = get_default_dist_name() end
+               if dist_name.empty? then raise RuntimeError,"Can't find distribution information" end
+               distribution = get_distribution( dist_name )
+
+               # distribution lock 
+               File.open("#{@location}/#{dist_name}/.lock_file", File::RDWR|File::CREAT, 0644) {|f|
+                       f.flock(File::LOCK_EX)
+                       f.rewind
+                       f.flush
+                       f.truncate(f.pos)
+               
+                       source_pkg_file_name_list = [] 
+                       updated_os_list = []
+                       append_pkg_list = []
+                       used_source_pkg_list = []
+                       package_list = []
+
+                       # error check 
+            source_pkg_file_path_list.each do |l| 
+                               # error check for file exist 
+                if not File.exist? l
+                                       raise RuntimeError, "source package file does not exist [#{l}]"
+                               end 
+
+                               source_pkg_file_name_list.push File.basename( l )
+                       end     
+            binary_pkg_file_path_list.each do |l| 
+                               # error check for file exist 
+                if not File.exist? l
+                                       raise RuntimeError, "binary package file does not exist [#{l}]"
+                               end 
+                       end     
+
+                       # register binary package
+            binary_pkg_file_path_list.each do |l| 
+                               # get package class using bianry file 
+                               pkg = distribution.get_package_from_file(l) 
+
+                               if pkg.nil? or pkg.package_name.empty? then
+                                       raise "[#{l}]'s pkginfo.manifest file is incomplete."
+                               end 
+                               package_list.push pkg
+
+                               if test then
+                                       if not pkg.source.empty? then   
+                                               if not source_pkg_file_name_list.include? "#{pkg.source}_#{pkg.version}.tar.gz"
+                                                       raise "binary package and source package must be upload same time"
+                                               end
+                                               
+                                               pkg.src_path = "/temp/#{pkg.source}_#{pkg.version}.tar.gz"
+                                       end
+                                       pkg = distribution.register_for_test(l ,pkg )
+                               else
+                                       if pkg.package_name.empty? or pkg.version.empty? or pkg.os.empty? or pkg.maintainer.empty? then
+                                               raise "[#{l}]'s pkginfo.manifest file is incomplete."
+                                       # binary only package
+                                       elsif pkg.attribute.include? "binary" then
+                                               @log.info "binary package [#{l}] is binary only package"
+                                               pkg.src_path = ""
+                                       elsif pkg.source.empty? then
+                                               raise "[#{l}]'s pkginfo.manifest file is incomplete." 
+                                       # binary package
+                                       else 
+                                               if not source_pkg_file_name_list.include? "#{pkg.source}_#{pkg.version}.tar.gz"
+                                                       raise "binary package [#{pkg.package_name}]'s source package must be upload same time"
+                                               end
+                                                       
+                                               @log.info "binary package [#{l}]'s source package is #{pkg.source}" 
+                                               used_source_pkg_list.push "#{pkg.source}_#{pkg.version}.tar.gz"
+                                               pkg.src_path = "/source/#{pkg.source}_#{pkg.version}.tar.gz"
+                                       end
+           
+                                       pkg = distribution.register(l ,pkg )
+                                       updated_os_list.push pkg.os 
+                               end
+                                       
+                               append_pkg_list.push pkg
+                       end 
+
+                       # check install dependency integrity
+                       if not test then distribution.check_instll_dependency_integrity end
+               
+                       source_pkg_file_path_list.each do |source_path|
+                               source_name = File.basename(source_path)
+                               if File.exist? "#{@location}/#{dist_name}/source/#{source_name}" then
+                                       @log.warn "source package already exist then does not register"
+                                       next
+                               end 
+
+                               if test then
+                                       @log.info "source package [#{source_name}] register in temp/]"
+                                       FileUtils.cp( source_path, "#{@location}/#{dist_name}/temp/" )
+                               else
+                                       @log.info "source package [#{source_name}] register in source/]"
+                                       FileUtils.cp( source_path, "#{@location}/#{dist_name}/source/" )
+                               end
+                       end 
+
+                       # register archive pakcage list. 
+                       distribution.write_archive_pkg_list( source_pkg_file_name_list - used_source_pkg_list )
+
+            binary_pkg_file_path_list.each do |l| 
+                               if test then 
+                                       FileUtils.cp( l, "#{@location}/#{dist_name}/temp/" )
+                               else 
+                                       FileUtils.cp( l, "#{@location}/#{dist_name}/binary/" )
+                               end
+                       end
+
+                       # write package list for updated os
+                       updated_os_list.uniq!
+                       updated_os_list.each do |os|
+               distribution.write_pkg_list( os ) 
+                       end
+
+            # if snapshot mode is true then generate snapshot 
+            if snapshot or test then
+                               @log.info "generaging snapshot"
+                distribution.generate_snapshot("", "", "")
+                       end 
+
+                       # send email
+                       if not test then 
+                               msg_list = []
+
+                               package_list.map{ |p| 
+                                               msg_list.push("%-30s: %08s" % [ p.package_name.strip, p.version.strip ] )
+                               } 
+                               # email just remote package server
+                               # Mail.send_package_registe_mail( msg_list, @id )  
+                       end
+        }
+    end
+
+       def generate_snapshot( snpashot_name, dist_name, base_snapshot, binary_pkg_file_path_list)
+               @log.info "generating snapshot"
+               if dist_name.empty? then dist_name = get_default_dist_name() end
+               if dist_name.empty? then raise RuntimeError,"Can't find distribution information" end
+               distribution = get_distribution( dist_name )
+
+               File.open("#{@location}/#{dist_name}/.lock_file", File::RDWR|File::CREAT, 0644) {|f|
+                       f.flock(File::LOCK_EX)
+                       f.rewind
+                       f.flush
+                       f.truncate(f.pos)
+                       
+                       append_pkg_list = []
+            binary_pkg_file_path_list.each do |l| 
+                               if not File.exist? l then raise RuntimeError,"Can't find binary package file [#{l}]" end
+                               pkg = distribution.get_package_from_file(l)
+                               if l.start_with? "/" 
+                                       pkg.path = "#{l}"
+                               else
+                                       pkg.path = "#{Dir.pwd}/#{l}"
+                               end
+                               append_pkg_list.push pkg
+            end 
+                       
+                       distribution.generate_snapshot( snpashot_name, base_snapshot, append_pkg_list)
+               }
+       end
+
+       def sync( dist_name, mode )
+               @log.info "sync from server"
+               if dist_name.empty? then dist_name = get_default_dist_name() end
+               if dist_name.empty? then raise RuntimeError,"Can't find distribution information" end
+               distribution = get_distribution( dist_name ) 
+       
+               if distribution.server_url.empty? then 
+                       @log.error( "This distribution has not remote server", Log::LV_USER) 
+                       return
+               end 
+
+               File.open("#{@location}/#{dist_name}/.lock_file", File::RDWR|File::CREAT, 0644) {|f|
+                       f.flock(File::LOCK_EX)
+                       f.rewind
+                       f.flush
+                       f.truncate(f.pos)
+            
+                       distribution.sync( mode, "linux" )
+                       distribution.sync( mode, "windows" )
+                       distribution.sync( mode, "darwin" )
+                       distribution.sync_archive_pkg
+               }
+       end
+
+       def add_distribution( dist_name, server_url, clone )
+               File.open("#{$server_create_loc_file}", File::RDWR|File::CREAT, 0644) {|f|
+                       f.flock(File::LOCK_EX)
+                       f.rewind
+                       f.flush
+                       f.truncate(f.pos)
+
+                       # error check : check for already exist in server directory 
+                       if @dist_to_server_url.keys.include? dist_name.strip then
+                               raise RuntimeError, "distribution already exist : #{dist_name}"
+                       end
+                       if File.exist? "#{@location}/#{dist_name}"
+                               raise RuntimeError, "distribution directory already exist [#{@location}/#{dist_name}]" 
+                       end
+            
+                       if (not server_url.empty?) and (not Utils.is_url_remote(server_url))
+                               # if server_url is local server address then generate absoulte path 
+                               if not Utils.is_absolute_path( server_url ) then 
+                                       if server_url.end_with?("/") then
+                                               server_url = Utils::WORKING_DIR + server_url 
+                                       else
+                                               server_url = Utils::WORKING_DIR + "/" + server_url 
+                                       end
+                               end
+                       end 
+
+                       File.open( "#{$server_root}/#{@id}/config", "a" ) do |f|
+                               if clone then 
+                                       @log.info "add distribution using [#{server_url}] in clone mode"
+                                       f.puts "server_url : #{dist_name} ->  "
+                               else
+                                       @log.info "add distribution using [#{server_url}]"
+                                       f.puts "server_url : #{dist_name} ->  #{server_url}"
+                               end
+                       end
+                       
+                       create_distribution_struct( dist_name, server_url )
+               }
+       end
+
+       def remove_server( id )
+               @log.info( "Package server [#{id}] will be removed and all server information delete", Log::LV_USER)
+
+               if File.exist? "#{$server_root}/#{id}/config" then
+                       File.open "#{$server_root}/#{id}/config" do |f|
+                               f.each_line do |l|
+                                       if l.start_with?( "location : ") then 
+                                               location= l.split(" : ")[1]
+                                               FileUtils.rm_rf l.split(" : ")[1].strip
+                                               @log.info( "server location removed : #{location}", Log::LV_USER)
+                                       end
+                               end
+                       end
+               else
+                       @log.error( "Can't find server information : #{id}", Log::LV_USER)
+               end 
+               
+               FileUtils.rm_rf "#{$server_root}/.#{id}.log"
+               FileUtils.rm_rf "#{$server_root}/#{id}"
+       end
+
+       def remove_pkg( id, dist_name, pkg_name_list )
+               @log.info "package remove in server"
+               if dist_name.empty? then dist_name = get_default_dist_name() end
+               if dist_name.empty? then raise RuntimeError,"Can't find distribution information" end
+               distribution = get_distribution( dist_name )
+
+               # distribution lock 
+               File.open("#{@location}/#{dist_name}/.lock_file", File::RDWR|File::CREAT, 0644) {|f|
+                       f.flock(File::LOCK_EX)
+                       f.rewind
+                       f.flush
+                       f.truncate(f.pos) 
+
+                       distribution.remove_pkg(pkg_name_list)
+               }
+       end
+
+       def find_source_package_path( dist_name, pkg_file_name_list ) 
+               if dist_name.empty? then dist_name = get_default_dist_name() end
+               if dist_name.empty? then raise RuntimeError,"Can't find distribution information" end
+               distribution = get_distribution( dist_name )
+
+               pkg_file_name_list.each do |pkg|
+                       pkg_path = "#{@location}/#{dist_name}/source/#{pkg}"
+                       if File.exist? pkg_path then
+                               @log.info( "#{pkg}", Log::LV_USER)
+                       else
+                               @log.error( "Can't find [#{pkg}] in source package", Log::LV_USER)
+                       end
+               end 
+       end
+
+       def PackageServer.list_id  
+               @@log = PackageServerLog.new( "#{$server_root}/.log", $stdout) 
+
+               d = Dir.new( $server_root )
+               s = d.select {|f| not f.start_with?(".") }  
+               s.sort!
+       
+               @@log.output( "=== server ID list ===", Log::LV_USER)
+               s.each do |id|
+                       @@log.output( id, Log::LV_USER)
+               end 
+       end
+
+       def PackageServer.list_dist( id )
+               @@log = PackageServerLog.new( "#{$server_root}/.log", $stdout) 
+               
+               @@log.output( "=== ID [#{id}]'s distribution list ===", Log::LV_USER)
+
+               # read package id information
+               if File.exist? "#{$server_root}/#{id}/config" then
+                       File.open "#{$server_root}/#{id}/config" do |f|
+                               f.each_line do |l|
+                                       if l.start_with?( "server_url : ") and l.include?( "->" ) then
+                                               @@log.output( l.split(" : ")[1].split("->")[0], Log::LV_USER)
+                                       end
+                               end
+                       end
+               else
+                       raise RuntimeError, "[#{id}] is not server ID"
+               end 
+       end
+
+       def get_default_dist_name() 
+               if @distribution_list.empty? then 
+                       raise RuntimeError,"Server [#{@id}] does not have distribution"
+               end 
+               return @distribution_list[0].name 
+       end
+
+       # PRIVATE METHODS/VARIABLES
+       private 
+
+       def server_information_initialize 
+               # if id is nil or empty then find default id
+               if @id.nil? or @id.empty? 
+                       d = Dir.new( $server_root )
+                       s = d.select {|f| not f.start_with?(".") }
+                       if s.length.eql? 1 then
+                               @log.info "using default server ID [#{s[0]}]"
+                               @id = s[0]
+                       else
+                               raise RuntimeError, "package server ID is invalid. input server ID using -i option"
+                       end
+               end
+
+               # read package id information
+               if File.exist? $server_root and File.exist? "#{$server_root}/#{@id}/config" then
+                       File.open "#{$server_root}/#{@id}/config" do |f|
+                               f.each_line do |l|
+                                       if l.start_with?( "location : ") then 
+                                               @location = l.split(" : ")[1].strip
+                                       elsif l.start_with?( "server_url : " ) then
+                                               info = l.split(" : ")[1].split("->")
+                                               @dist_to_server_url[info[0].strip] = info[1].strip 
+                                       else
+                                               @log.error "server config file has invalid information [#{l}]"
+                                       end
+                               end
+                       end
+               end
+       end
+
+       def set_distribution_list
+               @dist_to_server_url.each do |dist_name, server_url|
+                       @distribution_list.push Distribution.new( dist_name, "#{@location}/#{dist_name}", server_url,  @log)
+               end
+       end
+
+       def get_distribution( dist_name )
+               @distribution_list.each do |dist|
+                       if dist.name.eql? dist_name.strip
+                               return dist 
+                       end
+               end
+
+               raise RuntimeError, "Can't find distribution [ #{dist_name} ]"
+       end
+
+       def create_distribution_struct( dist_name, server_url )
+               FileUtils.mkdir "#{@location}/#{dist_name}"
+               FileUtils.mkdir "#{@location}/#{dist_name}/binary"
+               FileUtils.mkdir "#{@location}/#{dist_name}/source"
+               FileUtils.mkdir "#{@location}/#{dist_name}/temp"
+               FileUtils.mkdir "#{@location}/#{dist_name}/snapshots"
+           
+               # generate distribution
+               distribution = Distribution.new( dist_name, "#{@location}/#{dist_name}", server_url, @log )
+
+               # add dist
+               @distribution_list.push distribution
+       
+               if not server_url.empty?  then
+                       @log.info "generate package server using remote package server [#{server_url}]"
+
+                       if Utils.is_url_remote(server_url) then  
+                               @log.info "[#{dist_name}] distribution creation. using remote server [#{server_url}]"
+                       else 
+                               @log.info "[#{dist_name}] distribution creation. using local server [#{server_url}]"
+                       end
+
+                       distribution.sync( false, "linux" )
+                       distribution.sync( false, "windows" )
+                       distribution.sync( false, "darwin" )
+                       distribution.sync_archive_pkg
+               else
+                       @log.info "generate package server do not using remote package server"
+       
+                       # write_pkg_list for empty file
+                       distribution.write_pkg_list( "linux" )
+                       distribution.write_pkg_list( "windows" )
+                       distribution.write_pkg_list( "darwin" ) 
+                       distribution.write_archive_pkg_list( "" )
+               end
+       end
+end
+
diff --git a/src/pkg_server/packageServerLog.rb b/src/pkg_server/packageServerLog.rb
new file mode 100644 (file)
index 0000000..b20c798
--- /dev/null
@@ -0,0 +1,46 @@
+=begin
+ packageServerLog.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__)) + "/common"
+require "log"
+require "logger"
+
+class PackageServerLog < Log
+
+       def initialize(path, stream_out)
+               super(path)
+               @extra_out = stream_out
+       end
+
+       protected
+       def output_extra(msg)
+               @extra_out.puts msg
+       end     
+
+
+end
diff --git a/src/pkg_server/serverConfig.rb b/src/pkg_server/serverConfig.rb
new file mode 100644 (file)
index 0000000..9841d2b
--- /dev/null
@@ -0,0 +1,35 @@
+=begin
+ serverConfig.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "utils"
+
+$build_root = Utils::HOME + "/.build_root"
+$build_tools = Utils::HOME + "/.build_tools"
+$server_root = $build_tools + "/pkg_server"
+$server_create_loc_file = "#{$server_root}/.server_create_loc"
diff --git a/src/pkg_server/serverOptParser.rb b/src/pkg_server/serverOptParser.rb
new file mode 100644 (file)
index 0000000..bdacd82
--- /dev/null
@@ -0,0 +1,200 @@
+=begin
+ serverOptParser.rb 
+
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+
+Contact:
+Taejun Ha <taejun.ha@samsung.com>
+Jiil Hyoun <jiil.hyoun@samsung.com>
+Donghyuk Yang <donghyuk.yang@samsung.com>
+DongHee Yang <donghee.yang@samsung.com>
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+
+Contributors:
+- S-Core Co., Ltd
+=end
+
+require 'optparse'
+$LOAD_PATH.unshift File.dirname(File.dirname(__FILE__))+"/common"
+require "utils"
+
+def set_default( options ) 
+       if options[:id].nil? then options[:id] = "" end
+       if options[:dist].nil? then options[:dist] = "" end
+       if options[:url].nil? then options[:url] = "" end
+       if options[:os].nil? then options[:os] = "all" end
+       if options[:bpkgs].nil? then options[:bpkgs] = [] end
+       if options[:apkgs].nil? then options[:apkgs] = [] end
+       if options[:spkgs].nil? then options[:spkgs] = [] end
+       if options[:snap].nil? then options[:snap] = "" end
+       if options[:bsnap].nil? then options[:bsnap] = "" end
+       if options[:gensnap].nil? then options[:gensnap] = false end
+       if options[:force].nil? then options[:force] = false end
+       if options[:test].nil? then options[:test] = false end
+       if options[:clone].nil? then options[:clone] = false end
+end
+
+def option_error_check( options )
+               
+       case options[:cmd] 
+       when "create" 
+           if  options[:id].empty? or options[:dist].empty? then
+                       raise ArgumentError, "Usage: pkg-svr create -i <id> -d <distribution> [-u <remote_server_url>] [-l <location>] "
+               end
+       when "remove-pkg"
+               if      options[:bpkgs].empty? then
+               raise ArgumentError, "pkg-svr remove-pkg -i <id> -d <distribution> -p <binary_package_name_list> " + "\n" \
+               end
+       when "spkg-path"
+               if      options[:spkgs].empty? then
+               raise ArgumentError, "Usage: pkg-svr spkg-name -i <id> -d <distribution> -s <source_package_file_path> "
+               end
+       when "remove"
+               if      options[:id].empty? then
+               raise ArgumentError, "Usage: pkg-svr remove -i <id> "
+               end
+       when "add-dist"
+           if  options[:id].empty? or options[:dist].empty? then
+                       raise ArgumentError, "Usage: pkg-svr add-dist -i <id> -d <distribution> [-u <remote_server_url>] [-c] "
+               end
+       when "register"
+           if  options[:bpkgs].empty? and options[:spkgs].empty? then
+                       raise ArgumentError, "Usage: pkg-svr register -i <id> -d <distribution> -p <binary_package_file_path_list> -s <source_package_file_path_list> [-g] [-t] "
+               end
+       when "remove"
+       when "gen-snapshot"
+       when "sync"
+       when "list"
+       else
+               raise ArgumentError, "input option incorrect : #{options[:cmd]}"
+       end
+end
+
+def option_parse 
+    options = {}
+    banner = "Usage: pkg-svr {create|register|gen-snapshot|sync|add-dist|spkg-path|remove|remove-pkg|list|help} ..." + "\n" \
+        + "\t" + "pkg-svr create -i <id> -d <distribution> [-u <remote_server_url>] [-l <location>] " + "\n" \
+        + "\t" + "pkg-svr add-dist -i<id> -d <distribution> [-u <remote_server_url>] [-c] " + "\n" \
+        + "\t" + "pkg-svr remove -i <id> " + "\n" \
+        + "\t" + "pkg-svr register -i <id> -d <distribution> -p <binary_package_file_path_list> -s <source_package_file_path_list> [-g] [-t] " + "\n" \
+        + "\t" + "pkg-svr remove-pkg -i <id> -d <distribution> -p <binary_package_name_list> " + "\n" \
+        + "\t" + "pkg-svr gen-snapshot -i<id> -d <distribution> [-n <snapshot name>] [-b <base_snapshot_name>] [-p <binary_package_file_path_list>] " + "\n"  \
+        + "\t" + "pkg-svr sync -i <id> -d <distribution> [-f] " + "\n"  \
+        + "\t" + "pkg-svr spkg-path -i <id> -d <distribution> -s <source_package_name> " + "\n" \
+        + "\t" + "pkg-svr list [-i <id>] " + "\n" 
+
+    optparse = OptionParser.new do|opts|
+        # Set a banner, displayed at the top
+        # of the help screen.
+
+               opts.banner = banner 
+
+        opts.on( '-i', '--id <id>', 'package server id' ) do|name|
+            options[:id] = name 
+        end
+        
+               opts.on( '-d', '--dist <distribution>', 'package server distribution' ) do|dist|
+            options[:dist] = dist 
+        end
+               
+               opts.on( '-u', '--url <server_address>', 'remote server address' ) do|url|
+            options[:url] = url 
+        end
+               
+               opts.on( '-o', '--os <operating system>', 'target operating system' ) do|os|
+            options[:os] = os
+        end
+               
+               opts.on( '-p', '--bpackage <binary_pakcage_file_path_list>', 'binary package file path list' ) do|bpkgs|
+            options[:bpkgs] = []
+            list = bpkgs.tr(" \t","").split(",")
+            list.each do |l|
+                               # TODO: is not working
+                #reg = Regexp.new(l)
+                #Dir.entries(Utils::WORKING_DIR).select{|x| x =~ reg}.each do |ls|
+                #    options[:bpkgs].push ls
+                               #end 
+                               if l.start_with? "~" then l = Utils::HOME + l.delete("~") end
+                               options[:bpkgs].push l 
+            end 
+        end
+               
+               opts.on( '-s', '--spackage <source_pakcage_file_path_list>', 'source package file path ' ) do|spkgs|
+            options[:spkgs] = []
+            list = spkgs.tr(" \t","").split(",")
+            list.each do |l|
+                               if l.start_with? "~" then l = Utils::HOME + l.delete("~") end
+                               options[:spkgs].push l 
+            end 
+        end
+               
+               opts.on( '-g', '--generate', 'snapshot is generate' ) do
+            options[:gensnap] = true
+               end
+
+               opts.on( '-n', '--sname <snapshot>', 'snapshot name' ) do|snap|
+            options[:snap] = snap 
+        end
+               
+               opts.on( '-b', '--bsnapshot <base_snapshot_name>', 'base snapshot name' ) do|bsnap|
+            options[:bsnap] = bsnap 
+        end
+               
+               opts.on( '-l', '--location <location>', 'server location' ) do|loc|
+            options[:loc] = loc 
+        end
+               
+               opts.on( '-f', '--force', 'force update pkg file' ) do
+            options[:force] = true
+        end
+               
+               opts.on( '-t', '--test', 'upload for test' ) do
+            options[:test] = true
+        end
+               
+               opts.on( '-c', '--clone', 'clone mode' ) do
+            options[:clone] = true
+        end
+               
+               opts.on( '-h', '--help', 'display this information' ) do
+            puts opts
+                       exit
+        end
+               
+    end
+    
+       cmd = ARGV[0] 
+
+    if cmd.eql? "create" or cmd.eql? "register" or cmd.eql? "sync" \
+                       or cmd.eql? "gen-snapshot" or cmd.eql? "add-dist" \
+                       or cmd.eql? "spkg-path" or cmd.eql? "remove" \
+                       or cmd.eql? "list" or cmd.eql? "remove-pkg" or cmd =~ /(help)|(-h)|(--help)/  then
+        if cmd.eql? "help" then ARGV[0] = "-h" end
+        options[:cmd] = ARGV[0]
+    else
+        raise ArgumentError, banner
+    end
+
+    optparse.parse!
+   
+       # default value setting 
+       set_default options
+
+       # option error check 
+       option_error_check options
+
+    return options
+end 
+
diff --git a/test/a/a b/test/a/a
new file mode 100644 (file)
index 0000000..7898192
--- /dev/null
+++ b/test/a/a
@@ -0,0 +1 @@
+a
diff --git a/test/a/package/build.linux b/test/a/package/build.linux
new file mode 100755 (executable)
index 0000000..e056656
--- /dev/null
@@ -0,0 +1,35 @@
+#!/bin/bash  -e
+
+clean ()
+{
+    rm -rf $SRCDIR/*.zip
+    rm -rf $SRCDIR/*.tar.gz
+}
+
+build()
+{
+    if [ "`cat $ROOTDIR/b`" = "b" ] 
+    then 
+        echo "A: `cat $ROOTDIR/b` == b ... ok"
+    else
+        echo "A: `cat $ROOTDIR/b` != b ... fail"
+        exit 1
+    fi
+
+    if [ "`cat $ROOTDIR/c`" = "ca" ] 
+    then 
+        echo "A: `cat $ROOTDIR/c` == ca ... ok"
+    else
+        echo "A: `cat $ROOTDIR/c` != ca ... fail"
+        exit 1
+    fi
+}
+
+install()
+{
+    mkdir -p $SRCDIR/package/a.package.linux/data
+    cp $SRCDIR/a $SRCDIR/package/a.package.linux/data
+}
+
+$1
+echo "$1 success"
diff --git a/test/a/package/pkginfo.manifest b/test/a/package/pkginfo.manifest
new file mode 100644 (file)
index 0000000..bb9c561
--- /dev/null
@@ -0,0 +1,7 @@
+Package: a
+Version: 11
+OS: linux
+Maintainer: xxx
+Build-host-os: linux
+Build-dependency: b [linux], c [linux]
+Source: a
diff --git a/test/b/b b/test/b/b
new file mode 100644 (file)
index 0000000..6178079
--- /dev/null
+++ b/test/b/b
@@ -0,0 +1 @@
+b
diff --git a/test/b/package/build.linux b/test/b/package/build.linux
new file mode 100755 (executable)
index 0000000..83e5a6c
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/bash  -e
+
+clean ()
+{
+    rm -rf $SRCDIR/*.zip
+    rm -rf $SRCDIR/*.tar.gz
+}
+
+build()
+{
+    if [ "`cat $ROOTDIR/c`" = "ca" ] 
+    then 
+        echo "B: `cat $ROOTDIR/c` == ca ... ok"
+    else
+        echo "B: `cat $ROOTDIR/c` != ca ... fail"
+        exit 1
+    fi
+}
+
+install()
+{
+    mkdir -p $SRCDIR/package/b.package.linux/data
+    cp $SRCDIR/b $SRCDIR/package/b.package.linux/data
+}
+
+$1
+echo "$1 success"
diff --git a/test/b/package/pkginfo.manifest b/test/b/package/pkginfo.manifest
new file mode 100644 (file)
index 0000000..a164fd8
--- /dev/null
@@ -0,0 +1,7 @@
+Package: b
+Version: 11
+OS: linux
+Maintainer: xxx
+Build-host-os: linux
+Build-dependency: c [linux]
+Source: b
diff --git a/test/c/c b/test/c/c
new file mode 100644 (file)
index 0000000..16fc679
--- /dev/null
+++ b/test/c/c
@@ -0,0 +1 @@
+ca
diff --git a/test/c/package/build.linux b/test/c/package/build.linux
new file mode 100755 (executable)
index 0000000..b774e2d
--- /dev/null
@@ -0,0 +1,21 @@
+#!/bin/bash  -e
+
+clean ()
+{
+    rm -rf $SRCDIR/*.zip
+    rm -rf $SRCDIR/*.tar.gz
+}
+
+build ()
+{
+    echo "C: clean build (no dependency) ok"
+}
+
+install ()
+{
+    mkdir -p $SRCDIR/package/c.package.linux/data
+    cp $SRCDIR/c $SRCDIR/package/c.package.linux/data
+}
+
+$1
+echo "$1 success"
diff --git a/test/c/package/pkginfo.manifest b/test/c/package/pkginfo.manifest
new file mode 100644 (file)
index 0000000..ede7a91
--- /dev/null
@@ -0,0 +1,6 @@
+Package: c
+Version: 11
+OS: linux
+Build-host-os: linux
+Maintainer: xx
+Source: c
diff --git a/test/pkg-list b/test/pkg-list
new file mode 100644 (file)
index 0000000..cf64628
--- /dev/null
@@ -0,0 +1,24 @@
+Package : A
+Version : 0.1.0
+OS : linux
+Build-host-os :linux | windows | darwin
+Maintainer : taejun.ha <tajun.ha@samsung.com>
+Path : binary/A_0.1.0_linux.zip
+Origin : remote
+SHA256 : 52b400554f2a29dec46144af649181cf287c000b4feb65de72055ed9f11924a9
+
+Package: B
+Version : 0.2.0
+OS : linux
+Build-host-os :linux | windows | darwin
+Maintainer : taejun.ha <tajun.ha@samsung.com>
+Install-dependency : C, D, E
+Build-dependency : F (>= 1.0.0.20101221), E (>= 1.0.0.20101221)
+Source-dependency : D, scratchbox-aquila-simulator-rootstrap [    linux   |windows    ](>= 1.0.0.20101221), scratchbox-core [windows|darwin](>= 1.0.17)
+Path : 
+Source : Origin
+From-server? : true
+SHA256 : your_checksum
+Description : this is my first 
+project
+descriotion 
diff --git a/test/pkginfo.manifest b/test/pkginfo.manifest
new file mode 100644 (file)
index 0000000..ebace22
--- /dev/null
@@ -0,0 +1,35 @@
+Package : your_package
+Version : your_version
+OS : linux 
+Build-host-os:linux | windows | darwin 
+Maintainer : your_name <name@domain> name <name@domain>
+Install-dependency : codecoverage, rootstrap-slp-device-1.0, slp-ide
+Build-dependency : scratchbox-aquila-device-rootstrap (>= 1.0.0.20101221), scratchbox-aquila-simulator-rootstrap (>=    1.0.0.20101221), scratchbox-core (>= 1.0.17)
+Build-src-dependency : scratchbox-aquila-device-rootstrap   (>=     1.0.0.20101221)     [linux|windows], scratchbox-aquila-simulator-rootstrap [    linux   |windows    ](>= 1.0.0.20101221), scratchbox-core [windows|darwin](>= 1.0.17)
+Description : this is my first 
+project :
+descriotion :
+Attribute :
+Install-script :
+Remove-script :
+Category :
+Conflicts :
+Source : origin
+
+Package : your_package
+Version : your_version
+OS : windows
+Build-host-os:linux | windows | darwin 
+Maintainer : your_name <name@domain> name <name@domain>
+Install-dependency : codecoverage, rootstrap-slp-device-1.0, slp-ide
+Build-dependency : scratchbox-aquila-device-rootstrap (>= 1.0.0.20101221), scratchbox-aquila-simulator-rootstrap (>=    1.0.0.20101221), scratchbox-core (>= 1.0.17)
+Build-src-dependency : scratchbox-aquila-device-rootstrap   (>=     1.0.0.20101221)     [linux|windows], scratchbox-aquila-simulator-rootstrap [    linux   |windows    ](>= 1.0.0.20101221), scratchbox-core [windows|darwin](>= 1.0.17)
+Description : this is my first 
+project :
+descriotion :
+Attribute :
+Install-script :
+Remove-script :
+Category :
+Conflicts :
+Source : origin
diff --git a/test/test_bserver.rb b/test/test_bserver.rb
new file mode 100755 (executable)
index 0000000..f652e52
--- /dev/null
@@ -0,0 +1,27 @@
+#!/usr/bin/ruby 
+
+require File.dirname(__FILE__) + "/../src/common/utils"
+require File.dirname(__FILE__) + "/../src/build_server/BuildServerController"
+$SERVER_CONFIG_ROOT = Utils::HOME + "/.tizen_build_server"
+
+BuildServerController.remove_server("mbs_server_temp")
+BuildServerController.create_server("mbs_server_temp", Utils::WORKING_DIR, "http://172.21.111.132/pkgserver/unstable","pkgserver","pkgserver")
+BuildServerController.add_friend_server("mbs_server_temp", "172.21.111.177", 2222)
+=begin
+#case ARGV[0]
+#      when "create" then
+#              pkg_server.create "temp", "unstable", "http://172.21.111.132/pkgserver/", "unstable"
+#      when "register" then
+#              #pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", "-g"
+#              pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", ""
+#      when "snapshot" then 
+               pkg_server.snapshot_generate "", "unstable", "", "", ""
+       when "sync" then
+       #       pkg_server.sync "unstable", "force"
+               pkg_server.sync "unstable", ""
+       when "add_distribution" then
+               pkg_server.add_distribution "test_stable", "stable"
+       else
+               puts "First input error : #{ARGV[0]}"
+end
+=end
diff --git a/test/test_bserver2-1.rb b/test/test_bserver2-1.rb
new file mode 100755 (executable)
index 0000000..ce30e36
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/ruby 
+
+require File.dirname(__FILE__) + "/../src/common/utils"
+require File.dirname(__FILE__) + "/../src/build_server/BuildServerController"
+$SERVER_CONFIG_ROOT = Utils::HOME + "/.tizen_build_server"
+
+File.open("#{$SERVER_CONFIG_ROOT}/temp/.request","w") do |f|
+       f.puts("GIT,gerrithost:/slp/sdk/public/native/toolchain/smart-build-interface,master,linux")
+       f.puts("GIT,gerrithost:/slp/sdk/public/native/toolchain/sbi-slp-public-plugin,master,linux")
+end
+=begin
+#case ARGV[0]
+#      when "create" then
+#              pkg_server.create "temp", "unstable", "http://172.21.111.132/pkgserver/", "unstable"
+#      when "register" then
+#              #pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", "-g"
+#              pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", ""
+#      when "snapshot" then 
+               pkg_server.snapshot_generate "", "unstable", "", "", ""
+       when "sync" then
+       #       pkg_server.sync "unstable", "force"
+               pkg_server.sync "unstable", ""
+       when "add_distribution" then
+               pkg_server.add_distribution "test_stable", "stable"
+       else
+               puts "First input error : #{ARGV[0]}"
+end
+=end
diff --git a/test/test_bserver2.rb b/test/test_bserver2.rb
new file mode 100755 (executable)
index 0000000..85a95aa
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/ruby 
+
+require File.dirname(__FILE__) + "/../src/common/utils"
+require File.dirname(__FILE__) + "/../src/build_server/BuildServerController"
+$SERVER_CONFIG_ROOT = Utils::HOME + "/.build_tools/build_server"
+$BUILD_SERVER_HOST_OS = "linux"
+
+obj=BuildServerController.get_server("mbs_server_temp")
+puts obj.friend_servers[0].id
+BuildServerController.start_server("mbs_server_temp")
+=begin
+#case ARGV[0]
+#      when "create" then
+#              pkg_server.create "temp", "unstable", "http://172.21.111.132/pkgserver/", "unstable"
+#      when "register" then
+#              #pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", "-g"
+#              pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", ""
+#      when "snapshot" then 
+               pkg_server.snapshot_generate "", "unstable", "", "", ""
+       when "sync" then
+       #       pkg_server.sync "unstable", "force"
+               pkg_server.sync "unstable", ""
+       when "add_distribution" then
+               pkg_server.add_distribution "test_stable", "stable"
+       else
+               puts "First input error : #{ARGV[0]}"
+end
+=end
diff --git a/test/test_bserver2c.rb b/test/test_bserver2c.rb
new file mode 100755 (executable)
index 0000000..0d59deb
--- /dev/null
@@ -0,0 +1,25 @@
+#!/usr/bin/ruby 
+
+require File.dirname(__FILE__) + "/../src/build_server/BuildServerController"
+
+BuildServerController.build_git("mbs_server","gerrithost:/slp/sdk/public/native/toolchain/smart-build-interface","origin/unstable","linux", nil)
+
+#BuildServerController.build_local("temp","/home/bluleo78/git/sbi-slp-public-plugin/toolchains/public/gdb_build","linux")
+=begin
+#case ARGV[0]
+#      when "create" then
+#              pkg_server.create "temp", "unstable", "http://172.21.111.132/pkgserver/", "unstable"
+#      when "register" then
+#              #pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", "-g"
+#              pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", ""
+#      when "snapshot" then 
+               pkg_server.snapshot_generate "", "unstable", "", "", ""
+       when "sync" then
+       #       pkg_server.sync "unstable", "force"
+               pkg_server.sync "unstable", ""
+       when "add_distribution" then
+               pkg_server.add_distribution "test_stable", "stable"
+       else
+               puts "First input error : #{ARGV[0]}"
+end
+=end
diff --git a/test/test_bserver3.rb b/test/test_bserver3.rb
new file mode 100755 (executable)
index 0000000..94caec7
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/ruby 
+
+require File.dirname(__FILE__) + "/../src/common/utils"
+require File.dirname(__FILE__) + "/../src/build_server/BuildServerController"
+$SERVER_CONFIG_ROOT = Utils::HOME + "/.tizen_build_server"
+$BUILD_SERVER_HOST_OS = "linux"
+
+obj=BuildServerController.get_server("temp")
+File.open("#{$SERVER_CONFIG_ROOT}/temp/.request","w") do |f|
+#      f.puts("LOCAL,/home/bluleo78/git/sbi-slp-public-plugin/toolchains/public/gdb_build,linux,/home/bluleo78/test/test/unstable")
+end
+BuildServerController.start_server("temp")
diff --git a/test/test_bserver3c.rb b/test/test_bserver3c.rb
new file mode 100755 (executable)
index 0000000..28b1564
--- /dev/null
@@ -0,0 +1,28 @@
+#!/usr/bin/ruby 
+
+require File.dirname(__FILE__) + "/../src/common/utils"
+require File.dirname(__FILE__) + "/../src/build_server/BuildServerController"
+$SERVER_CONFIG_ROOT = Utils::HOME + "/.tizen_build_server"
+
+#BuildServerController.build_git("temp","gerrithost:/slp/sdk/public/native/toolchain/smart-build-interface","origin/unstable","linux")
+sleep 5
+
+BuildServerController.build_local("temp","/home/bluleo78/git/sbi-slp-public-plugin/toolchains/public/gdb_build","linux","/home/bluleo78/test/test/unstable")
+=begin
+#case ARGV[0]
+#      when "create" then
+#              pkg_server.create "temp", "unstable", "http://172.21.111.132/pkgserver/", "unstable"
+#      when "register" then
+#              #pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", "-g"
+#              pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", ""
+#      when "snapshot" then 
+               pkg_server.snapshot_generate "", "unstable", "", "", ""
+       when "sync" then
+       #       pkg_server.sync "unstable", "force"
+               pkg_server.sync "unstable", ""
+       when "add_distribution" then
+               pkg_server.add_distribution "test_stable", "stable"
+       else
+               puts "First input error : #{ARGV[0]}"
+end
+=end
diff --git a/test/test_client.rb b/test/test_client.rb
new file mode 100755 (executable)
index 0000000..68d5ba2
--- /dev/null
@@ -0,0 +1,57 @@
+#!/usr/bin/ruby
+
+require File.dirname(__FILE__) + "/../src/pkg_server/client"
+require File.dirname(__FILE__) + "/../src/pkg_server/serverConfig"
+
+### Client.new("server","dist","snapshot","location") 
+
+# local server
+#cl = Client.new("/home/yangttak/test-packageserver")
+
+# remote server
+cl = Client.new("http://172.21.111.132/pkgserver/unstable", "/home/yangttak/build_root")
+#cl.update()
+result = cl.get_install_dependent_packages("cross-arm-gcc-4.5", "linux", true)
+puts "----"
+puts result
+
+result = cl.get_install_dependent_packages("cross-arm-gcc-4.5", "linux", false)
+puts "----"
+puts result
+
+result = cl.get_build_dependent_packages("tizen-image-creator", "linux", true)
+puts "----"
+puts result
+#cl.upload("pkgserver", "first", "unstable", nil, "/home/yangttak/test0208/sdk-build/test/test_downloader.rb")
+#cl.install_local_pkg("/home/yangttak/test0208/sdk-build/smart-build-interface_0.20.0_linux.zip", "linux")
+#cl.show_pkg_info("tizen-ide", "linux")
+
+#cl = Client.new("http://172.21.111.132/pkgserver/unstable/snapshot/snapshot3-linux", "/tmp/client-test")
+#cl.update()
+#result = cl.get_install_dependent_packages("smart-build-interface", "linux")
+#puts result
+
+# if location is nil
+#cl = Client.new("http://172.21.111.132/pkgserver/unstable", nil)
+
+# if server addr is nil
+#cl = Client.new(nil, "/tmp/client-test")
+
+# install package list
+#cl.download("base-toolchain", "windows")
+
+# test install different veriosn package
+#cl = Client.new("http://172.21.111.132/pkgserver/unstable/snapshot/snapshot2-linux", "/tmp/client-test")
+#cl.install("tizen-ide", "linux")
+#cl.install("smart-build-interface", "linux")
+
+
+#cl = Client.new("http://172.21.111.132/pkgserver/unstable", "/tmp/client-test")
+#result = cl.get_build_dependent_packages("mpfr", "linux")
+#puts result
+#result = cl.get_install_dependent_packages("arm-linux-gnueabi-gdb-7.2", "linux")
+#puts result
+#result = cl.get_install_dependent_packages("smart-build-interface", "linux")
+#puts result
+
+
diff --git a/test/test_downloader.rb b/test/test_downloader.rb
new file mode 100755 (executable)
index 0000000..008dd1c
--- /dev/null
@@ -0,0 +1,12 @@
+#!/usr/bin/ruby
+
+require File.dirname(__FILE__) + "/../src/pkg_server/downloader"
+require File.dirname(__FILE__) + "/../src/pkg_server/serverConfig"
+
+### FileDownLoader.download(source url, target path)
+
+# download local package
+# FileDownLoader.download("/home/yangttak/gmp-5.0.1.tar.gz", ".")
+
+# download remote package
+FileDownLoader.download("http://172.21.111.132/pkgserver/unstable/source/gmp-5.0.1.tar.gz", $download_temp)
diff --git a/test/test_installer.rb b/test/test_installer.rb
new file mode 100755 (executable)
index 0000000..66d86b4
--- /dev/null
@@ -0,0 +1,10 @@
+#!/usr/bin/ruby
+
+require File.dirname(__FILE__) + "/../src/pkg_server/downloader"
+require File.dirname(__FILE__) + "/../src/pkg_server/installer"
+require File.dirname(__FILE__) + "/../src/pkg_server/serverConfig"
+
+FileDownLoader.download("http://172.21.111.132/pkgserver/unstable/source/gmp-5.0.1.tar.gz", $download_temp)
+
+### FileInstaller.install(package_name, source_file_path, package_type, target_path)
+FileInstaller.install("gmp","#{$download_temp}/gmp-5.0.1.tar.gz", "binary", $build_root)
diff --git a/test/test_pkglist_parser.rb b/test/test_pkglist_parser.rb
new file mode 100755 (executable)
index 0000000..c299f7f
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/ruby
+require '../src/common/parser'
+require '../src/common/package'
+
+alist = Parser.read_pkg_list "pkg-list"
+a_list = alist.values
+a_list.each do |l|
+    l.print
+end 
diff --git a/test/test_server b/test/test_server
new file mode 100755 (executable)
index 0000000..64bdb77
--- /dev/null
@@ -0,0 +1,65 @@
+#!/bin/sh 
+
+echo "============ remove 1 =============="
+../pkg-svr remove -i temp_local
+echo "============ remove 2 =============="
+../pkg-svr remove -i temp_remote
+echo "============ remove 3 =============="
+../pkg-svr remove -i temp_remote_dup
+echo "============ remove 4 =============="
+../pkg-svr remove -i temp_remote_snap
+echo "============ create 1 =============="
+../pkg-svr create -i temp_local -d unstable 
+echo "============ create 2 =============="
+../pkg-svr create -i temp_remote -d unstable -u http://172.21.17.55/pkgserver/unstable 
+echo "============ create 3 =============="
+../pkg-svr create -i temp_remote_dup -d unstable -u temp_remote/unstable
+echo "============ add dist 1 =============="
+../pkg-svr add-dist -i temp_local -d stable 
+echo "============ sync 1 =============="
+../pkg-svr sync -i temp_remote -d unstable 
+echo "============ sync 2 =============="
+../pkg-svr sync -i temp_remote_dup -d unstable -f
+echo "============ gen snapshot 1 =============="
+../pkg-svr gen-snapshot        -i temp_remote
+echo "============ gen snapshot 2 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable 
+echo "============ gen snapshot 3 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable -n test
+echo "============ gen snapshot 4 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable -n test2 -b test 
+echo "============ gen snapshot 5 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable -o linux
+echo "============ gen snapshot 6 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable -o windows
+echo "============ gen snapshot 7 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable -o darwin
+echo "============ gen snapshot 8 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable -o all 
+echo "============ gen snapshot 9 =============="
+../pkg-svr gen-snapshot -i temp_remote -d unstable -o all -p test_server_pkg_file/smart-build-interface_1.20.1_linux.zip -n test3
+echo "============ create 4 =============="
+../pkg-svr create -i temp_remote_snap -d unstable -u temp_remote/unstable/snapshots/test
+echo "============ register 1 =============="
+cp test_server_pkg_file/smart-build-interface_1.20.1_linux.zip ./smart-build-interface_1.20.1_linux.zip 
+cp test_server_pkg_file/smart-build-interface_1.20.1.tar.gz ./smart-build-interface_1.20.1.tar.gz
+../pkg-svr register -i temp_remote -d unstable -p smart-build-interface_1.20.1_linux.zip -s smart-build-interface_1.20.1.tar.gz -g
+echo "============ spkg path 1 =============="
+../pkg-svr spkg-path -i temp_remote -d unstable -s smart-build-interface_1.20.1.tar.gz
+echo "============ register 2 =============="
+cp test_server_pkg_file/smart-build-interface_1.20.1_linux.zip ./smart-build-interface_1.20.1_linux.zip 
+cp test_server_pkg_file/smart-build-interface_1.20.1.tar.gz ./smart-build-interface_1.20.1.tar.gz
+../pkg-svr register -i temp_remote -d unstable -p smart-build-interface_1.20.1_linux.zip -s smart-build-interface_1.20.1.tar.gz -g
+echo "============ register 3 =============="
+../pkg-svr register -i temp_remote_dup -d unstable -p ./temp_remote/unstable/binary/smart-build-interface_1.20.1_linux.zip -s ./temp_remote/unstable/source/smart-build-interface_1.20.1.tar.gz -g -t
+echo "============ remove 3 ==============" 
+../pkg-svr remove-pkg -i temp_remote_dup -d unstable -p smart-build-interface
+echo "============ list 1 =============="
+../pkg-svr list
+echo "============ list 2 =============="
+../pkg-svr list -i temp_local
+#../pkg-svr remove -i temp
+
+#cleanup
+rm smart-build-interface_1.20.1_linux.zip 
+rm smart-build-interface_1.20.1.tar.gz
diff --git a/test/test_server.rb b/test/test_server.rb
new file mode 100755 (executable)
index 0000000..b573a82
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/ruby 
+
+require File.dirname(__FILE__) + "/../src/common/utils"
+require File.dirname(__FILE__) + "/../src/pkg_server/packageServer"
+
+pkg_server = PackageServer.new "temp"
+
+case ARGV[0]
+       when "create" then
+               pkg_server.create "temp", "unstable", "http://172.21.111.132/pkgserver/", "unstable"
+       when "register" then
+               #pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", "-g"
+               pkg_server.register "/home/taejun/project/sdk-build/test/smart-build-interface_0.19.1_linux.zip", "unstable", ""
+       when "snapshot" then 
+               pkg_server.snapshot_generate "", "unstable", "", "", ""
+       when "sync" then
+       #       pkg_server.sync "unstable", "force"
+               pkg_server.sync "unstable", ""
+       when "add_distribution" then
+               pkg_server.add_distribution "test_stable", "stable"
+       else
+               puts "First input error : #{ARGV[0]}"
+end
+
diff --git a/test/test_server_pkg_file/smart-build-interface_1.20.1.tar.gz b/test/test_server_pkg_file/smart-build-interface_1.20.1.tar.gz
new file mode 100644 (file)
index 0000000..96f13b4
Binary files /dev/null and b/test/test_server_pkg_file/smart-build-interface_1.20.1.tar.gz differ
diff --git a/test/test_server_pkg_file/smart-build-interface_1.20.1_linux.zip b/test/test_server_pkg_file/smart-build-interface_1.20.1_linux.zip
new file mode 100644 (file)
index 0000000..109a144
Binary files /dev/null and b/test/test_server_pkg_file/smart-build-interface_1.20.1_linux.zip differ
diff --git a/test/test_utils.rb b/test/test_utils.rb
new file mode 100755 (executable)
index 0000000..4945064
--- /dev/null
@@ -0,0 +1,7 @@
+#!/usr/bin/ruby
+
+require File.dirname(__FILE__) + "/../src/common/utils"
+
+result = Utils.compare_version("5.2", "5.0.1")
+puts result
+
diff --git a/test/tpkg/.log b/test/tpkg/.log
new file mode 100644 (file)
index 0000000..5bb7d9b
--- /dev/null
@@ -0,0 +1,31 @@
+# Logfile created on Tue Feb 07 04:41:32 +0900 2012 by logger.rb/22285
+I, [2012-02-07T04:41:32.501856 #8938]  INFO -- : option parsing start
+I, [2012-02-07T04:41:32.502027 #8938]  INFO -- : option is : 
+I, [2012-02-07T04:41:32.502149 #8938]  INFO -- : option parsing end
+I, [2012-02-07T04:41:58.085604 #8964]  INFO -- : option parsing start
+I, [2012-02-07T04:41:58.085807 #8964]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T04:41:58.085997 #8964]  INFO -- : option parsing end
+I, [2012-02-07T04:42:23.693462 #9000]  INFO -- : option parsing start
+I, [2012-02-07T04:42:23.693562 #9000]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T04:42:23.693652 #9000]  INFO -- : option parsing end
+I, [2012-02-07T04:56:31.754070 #10355]  INFO -- : option parsing start
+I, [2012-02-07T04:56:31.754269 #10355]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T04:56:31.754475 #10355]  INFO -- : option parsing end
+I, [2012-02-07T05:00:28.494119 #10628]  INFO -- : option parsing start
+I, [2012-02-07T05:00:28.494318 #10628]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T05:00:28.494519 #10628]  INFO -- : option parsing end
+I, [2012-02-07T05:05:54.803965 #11007]  INFO -- : option parsing start
+I, [2012-02-07T05:05:54.804057 #11007]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T05:05:54.804147 #11007]  INFO -- : option parsing end
+I, [2012-02-07T05:11:20.088453 #11415]  INFO -- : option parsing start
+I, [2012-02-07T05:11:20.088549 #11415]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T05:11:20.088641 #11415]  INFO -- : option parsing end
+I, [2012-02-07T05:12:13.094058 #11504]  INFO -- : option parsing start
+I, [2012-02-07T05:12:13.094152 #11504]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T05:12:13.094241 #11504]  INFO -- : option parsing end
+I, [2012-02-07T05:32:29.151717 #12638]  INFO -- : option parsing start
+I, [2012-02-07T05:32:29.151917 #12638]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T05:32:29.152123 #12638]  INFO -- : option parsing end
+I, [2012-02-07T05:43:03.812225 #12775]  INFO -- : option parsing start
+I, [2012-02-07T05:43:03.813711 #12775]  INFO -- : option is : -u,http://172.21.111.132/testserver/unstable
+I, [2012-02-07T05:43:03.816670 #12775]  INFO -- : option parsing end
diff --git a/test/tpkg/package/build.linux b/test/tpkg/package/build.linux
new file mode 100755 (executable)
index 0000000..42d402e
--- /dev/null
@@ -0,0 +1,40 @@
+#!/bin/sh -x
+# clean
+clean()
+{
+       rm -rf $SRCDIR/*.zip
+       rm -rf $SRCDIR/*.tar.gz
+       rm -rf $SRCDIR/*.package.linux
+}
+
+# build
+build() 
+{
+    touch own
+    touch two
+    touch three
+    touch four
+}
+
+# install
+install() 
+{
+       build
+
+       BIN_DIR=$SRCDIR/package
+       mkdir -p $BIN_DIR/pkgone.package.linux
+       mkdir -p $BIN_DIR/pkgtwo.package.linux
+       mkdir -p $BIN_DIR/pkgthree.package.linux
+       mkdir -p $BIN_DIR/pkgfour.package.linux
+    mv own $BIN_DIR/pkgone.package.linux
+    mv two $BIN_DIR/pkgtwo.package.linux
+    mv three $BIN_DIR/pkgthree.package.linux
+    mv four $BIN_DIR/pkgfour.package.linux
+}
+
+
+
+[ "$1" = "clean" ] && clean
+[ "$1" = "build" ] && build
+[ "$1" = "install" ] && install
+exit 0
diff --git a/test/tpkg/package/pkgfour.install b/test/tpkg/package/pkgfour.install
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/test/tpkg/package/pkgfour.remove b/test/tpkg/package/pkgfour.remove
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/test/tpkg/package/pkginfo.manifest b/test/tpkg/package/pkginfo.manifest
new file mode 100644 (file)
index 0000000..eab9277
--- /dev/null
@@ -0,0 +1,71 @@
+Package : pkgone
+Version : 0.1.0
+OS : linux | windows
+Mintainer : pkgone owner <owner@pkgone>
+Install-dependency : pkgtwo (>= 0.2.0)  [linux | windows], pkgthree (<= 0.3.0 ) [linux] 
+Build-dependency : pkgtwo (>= 0.2.0)  [linux | windows], pkgthree (<= 0.3.0 ) [linux] 
+Source-dependency : tpkg
+# this is commant 
+Attribute : hi
+Category : my Category
+Conflict : pkgfour
+Install-script : pkgone.install
+Remove-script : pkgone.remove
+Source : tpkg
+Description : first test package 
+--
+it will increase 
+
+Package : pkgtwo
+Version : 0.2.0
+OS : linux | windows
+Mintainer : pkgone owner <owner@pkgone>
+Install-dependency : pkgone (>= 0.1.0)  [linux | windows], pkgthree (<= 0.3.0 ) [linux] 
+Build-dependency : pkgone (>= 0.1.0)  [linux | windows], pkgthree (<= 0.3.0 ) [linux] 
+Source-dependency : tpkg
+# this is commant 
+Attribute : E
+Category : ouu Category
+Conflict : pkgfour
+Install-script : pkgtwo.install
+Remove-script : pkgtwo.remove
+Source : tpkg
+Description : second test package 
+--
+it will increase 
+
+Package : pkgthree
+Version : 0.3.0
+OS : linux | darwin 
+Mintainer : pkgone owner <owner@pkgone>
+Install-dependency : pkgtwo (>= 0.2.0)  [linux | windows]
+Build-dependency : pkgtwo (>= 0.2.0)  [linux | windows], pkgone (<= 0.1.0 ) [linux] 
+Source-dependency : tpkg
+# this is commant 
+Attribute : sam
+Category : sam Category
+Conflict : pkgfour
+Install-script : pkgthree.install
+Remove-script : pkgthree.remove
+Source : tpkg
+Description : 3rd test package 
+--
+it will increase 
+
+Package : pkgfour
+Version : 0.4.0
+OS : linux | darwin 
+Mintainer : pkgone owner <owner@pkgone>
+Install-dependency : pkgthree (<= 0.3.0 ) [linux] 
+Build-dependency : pkgone (>= 0.1.0)  [linux | windows], pkgthree (<= 0.3.0 ) [linux] 
+Source-dependency : tpkg
+# this is commant 
+Attribute : i for 
+Category : you Category
+Conflict : pkgfour
+Install-script : pkgfour.install
+Remove-script : pkgfour.remove
+Source : tpkg
+Description : 4th test package 
+--
+it will increase 
diff --git a/test/tpkg/package/pkgone.install b/test/tpkg/package/pkgone.install
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/test/tpkg/package/pkgone.remove b/test/tpkg/package/pkgone.remove
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/test/tpkg/package/pkgthree.install b/test/tpkg/package/pkgthree.install
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/test/tpkg/package/pkgthree.remove b/test/tpkg/package/pkgthree.remove
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/test/tpkg/package/pkgtwo.install b/test/tpkg/package/pkgtwo.install
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/test/tpkg/package/pkgtwo.remove b/test/tpkg/package/pkgtwo.remove
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh