support work_dir and buildconf options in gbs config, #1008
authorZhang Qiang <qiang.z.zhang@intel.com>
Thu, 6 Jun 2013 06:46:22 +0000 (14:46 +0800)
committerZhang Qiang <qiang.z.zhang@intel.com>
Thu, 6 Jun 2013 23:21:18 +0000 (07:21 +0800)
work_dir is the topdir of all tizen source packages, and pre-built
build-conf git project will under that directory based on latest tizen
source code structure.

The new conf manager also support string interpolation, expecially for
work_dir, which can be used in specifying pre-built dir and build conf

build conf can be specified in gbs.conf now.

Examples of gbs.conf:

    [general]
    tmpdir=/var/tmp/export_dir/
    profile = profile.tizen2.1
    work_dir=~/local-source

    [repo.tizen2.1]
    url=${work_dir}/pre-built/

    [profile.tizen2.1]
    repos=repo.tizen2.1
    buildconf=${work_dir}/project-conf/build.conf

Structure of tizen source code

$ cd ~/local-source
$ tree .
  .
  |-- gbs-conf
  |   `-- gbs.conf
  |-- pre-built
  |-- project-conf
  |-- framework
  |-- ...
  `-- toolchains

Change-Id: Ia0e47500523dae09e90c0d4bee115e46628e3368

gitbuildsys/cmd_build.py
gitbuildsys/conf.py

index a49c04b..5012a2e 100644 (file)
@@ -117,6 +117,8 @@ def prepare_repos_and_build_conf(args, arch, profile):
         if not os.path.exists(args.dist):
             raise GbsError('specified build conf %s does not exist' % args.dist)
         shutil.copy(args.dist, distconf)
+    elif profile.buildconf:
+        shutil.copy(profile.buildconf, distconf)
     else:
         if repoparser.buildconf is None:
             raise GbsError('failed to get build conf from repos, please '
index ce0ed29..077235a 100644 (file)
@@ -21,6 +21,7 @@ Provides classes and functions to read and write gbs.conf.
 
 from __future__ import with_statement
 import os
+import re
 import base64
 import shutil
 from collections import namedtuple
@@ -177,6 +178,7 @@ class ConfigMgr(object):
                 'squash_patches_until': '',
                 'buildroot':    '~/GBS-ROOT/',
                 'packaging_dir': 'packaging',
+                'work_dir': '.',
             },
     }
 
@@ -256,6 +258,10 @@ url = http://download.tizen.org/releases/daily/trunk/ivi/latest/
             cfgparser = BrainConfigParser()
             try:
                 cfgparser.read_one(fpath)
+                if cfgparser.has_section('general') and \
+                   cfgparser.has_option('general', 'work_dir'):
+                    cfgparser.set('general', 'work_dir',
+                                  os.path.abspath(os.path.dirname(fpath)))
             except Error, err:
                 raise errors.ConfigError('config file error:%s' % err)
             self._cfgparsers.append(cfgparser)
@@ -272,6 +278,24 @@ url = http://download.tizen.org/releases/daily/trunk/ivi/latest/
         """
 
         paths = []
+
+        def lookfor_tizen_conf(start_dir):
+            """ Search topdir of tizen source code cloned using repo tool,
+            if .gbs.conf exists under that dir, then return it
+            """
+            cur_dir = os.path.abspath(start_dir)
+            while True:
+                cur_dir = os.path.dirname(cur_dir)
+                if cur_dir == '/':
+                    break
+                if os.path.exists(os.path.join(cur_dir, '.repo')) and \
+                   os.path.exists(os.path.join(cur_dir, '.gbs.conf')):
+                    return os.path.join(cur_dir, '.gbs.conf')
+            return None
+
+        tizen_conf = lookfor_tizen_conf(os.getcwd())
+        if tizen_conf:
+            paths.append(tizen_conf)
         for path in (os.path.abspath('.gbs.conf'),
                      os.path.expanduser('~/.gbs.conf'),
                      '/etc/gbs.conf'):
@@ -424,6 +448,7 @@ class Profile(object):
         self.repos = []
         self.obs = None
         self.buildroot = None
+        self.buildconf = None
 
     def add_repo(self, repoconf):
         '''add a repo to repo list of the profile'''
@@ -463,6 +488,22 @@ class BizConfigManager(ConfigMgr):
     '''config manager which handles high level conception, such as profile info
     '''
 
+
+    def _interpolate(self, value):
+        '''do string interpolation'''
+
+        general_keys = {}
+
+        for opt in self.DEFAULTS['general']:
+            if opt == 'work_dir' and self.get(opt, 'general') == '.':
+                general_keys[opt] = os.getcwd()
+            else:
+                general_keys[opt] = self.get(opt, 'general')
+
+        value = re.sub(r'\$\{([^}]+)\}', r'%(\1)s', value)
+        value = value % general_keys
+        return value
+
     def is_profile_oriented(self):
         '''return True if config file is profile oriented'''
         return self.get_optional_item('general', 'profile') is not None
@@ -513,7 +554,7 @@ class BizConfigManager(ConfigMgr):
 
     def _get_url_options(self, section_id):
         '''get url/user/passwd from a section'''
-        url = self.get('url', section_id)
+        url = os.path.expanduser(self._interpolate(self.get('url', section_id)))
         user = self.get_optional_item(section_id, 'user')
         password = self.get_optional_item(section_id, 'passwd')
         return URL(url, user, password)
@@ -557,7 +598,10 @@ class BizConfigManager(ConfigMgr):
                 profile.add_repo(repoconf)
 
         profile.buildroot = self.get_optional_item(name, 'buildroot')
-
+        if self.get_optional_item(name, 'buildconf'):
+            profile.buildconf = os.path.expanduser(self._interpolate(
+                                                   self.get_optional_item(name,
+                                                   'buildconf')))
         return profile
 
     def _parse_build_repos(self):