Add new job 'check_scm_meta_git'. It's for using scm/meta/git. 01/73701/2
authorSehong Na <sehong.na@samsung.com>
Thu, 9 Jun 2016 07:49:40 +0000 (16:49 +0900)
committerSehong Na <sehong.na@samsung.com>
Thu, 9 Jun 2016 08:15:56 +0000 (17:15 +0900)
- Synchronize meta data in scm/meta/git to gerrit system automatically.
- Check syntax & semantics about scm/meta/git.

Change-Id: I552f6a0011a7b977f6221e309d2127ef2d95905b
Signed-off-by: Sehong Na <sehong.na@samsung.com>
common/apply_scm_meta_git.py [new file with mode: 0644]
common/check_scm_meta_git.py [new file with mode: 0644]
common/git_diff_parse.py [new file with mode: 0644]
job_check_scm_meta_git.py [new file with mode: 0755]
scripts/check_section.sh [new file with mode: 0755]
scripts/get_git_desc_info.sh [new file with mode: 0755]

diff --git a/common/apply_scm_meta_git.py b/common/apply_scm_meta_git.py
new file mode 100644 (file)
index 0000000..8b34808
--- /dev/null
@@ -0,0 +1,230 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 Samsung
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU General Public License
+#    as published by the Free Software Foundation; version 2
+#    of the License.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+"""Apply meta data from file to system."""
+
+import os
+import subprocess
+import collections
+import git_diff_parse
+
+class Server:
+    def __init__(self, port, account, url):
+        self.port = port
+        self.account = account
+        self.url = url
+
+class SyntaxError(Exception):
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return self.value
+
+def get_diff_info(dic):
+        obj_list = []
+
+        git_diff_parse.git_diff_parse(obj_list)
+        for i in range(len(obj_list)):
+                for j in range(len(meta_file_list)):
+                        if obj_list[i][1] == meta_file_list[j]:
+                                dic[meta_file_list[j]].append(obj_list[i][:])
+                                break
+
+def get_key_list(dic, readme_file):
+        with open('%s' % readme_file, 'r') as lines:
+                read_status = False
+                cur_file = ''
+                for line in lines:
+                        if line.split(':')[0] == 'Filename':
+                                cur_file = line.split(':')[1].split('"')[1]
+                if cur_file in meta_file_list:
+                                    read_status = True
+                                continue
+                        if read_status:
+                                if line.strip() == '':
+                                        read_status = False
+                                else:
+                    temp = line.strip().split(' ')
+                    if temp[len(temp) - 2] + ' ' + temp[len(temp) - 1] == 'Read Only':
+                        attr = 1
+                    else:
+                        attr = 0
+                                        dic[cur_file][line.strip()[0]] = attr
+
+def init_info(file_list, readme_file, sdir):
+    global meta_file_list
+    global meta_info
+    global key_list
+    global scripts_dir
+
+    meta_file_list = []
+    meta_info = {}
+    key_list = {}
+    scripts_dir = sdir
+
+    for i in range(len(file_list)):
+        meta_file_list.append(file_list[i])
+        meta_info[file_list[i]] = []
+        key_list[file_list[i]] = collections.OrderedDict()
+
+    get_diff_info(meta_info)
+    get_key_list(key_list, readme_file)
+
+    global group_list
+    global changed_git_list
+    global description_list
+
+    group_list = {'A' : 'Architects', 'M' : 'Maintainers', 'I' : 'Integrators', 'R' : 'Reviewers'}
+    git_domain = {}
+    changed_git_list = set()
+    description_list = collections.OrderedDict()
+    description_list['D'] = 'Domain'
+    description_list['O'] = 'Owners'
+    description_list['L'] = 'Licenses'
+    description_list['C'] = 'Comments'
+
+def print_message(status, fn, ln, lm, comment):
+    if status == 'OK':
+        print("[%s, %d, OK] %s - %s" % (fn, ln, lm, comment))
+    else:
+        print("[%s, %d, Error] %s - %s" % (fn, ln, lm, comment))
+        return "[%s, %d, Error] %s - %s" % (fn, ln, lm, comment)
+
+def find_section(line_num, index):
+        return subprocess.check_output('%s/check_section.sh %d %s' % (scripts_dir, line_num, index), shell = True)
+
+def arrange_desc(desc_list, git_list):
+    git_desc_list = {}
+    ret_list = []
+
+    for i in range(len(git_list)):
+        for key in description_list.keys():
+            git_desc_list[key] = []
+        for j in range(len(desc_list[i])):
+            if len(desc_list[i][j]) == 0:
+                continue
+            key = desc_list[i][j][0]
+            if key in git_desc_list:
+                git_desc_list[key].append(desc_list[i][j].split('%s: ' % key)[1])
+
+        final_desc = ""
+        for key in description_list.keys():
+            if len(git_desc_list[key]) == 0:
+                continue
+            final_desc = final_desc + description_list[key] + ': '
+            for k in range(len(git_desc_list[key])):
+                final_desc = final_desc + git_desc_list[key][k] + ', '
+            final_desc = final_desc.rstrip(', ')
+            final_desc = final_desc + '; '
+        final_desc = final_desc.rstrip(' ')
+
+          ret_list.append([git_list[i], final_desc])
+
+    return ret_list
+
+def get_desc_list(git_list):
+    ret_list = []
+    for i in range(len(git_list)):
+        ret_list.append(subprocess.check_output('%s/get_git_desc_info.sh %s' % (scripts_dir, git_list[i]), shell = True))
+        ret_list[i] = ret_list[i].strip().split(';')
+        del ret_list[i][len(ret_list[i]) - 1]
+    return arrange_desc(ret_list, git_list)
+
+def get_domain_info(name, server):
+    return subprocess.check_output("ssh -p %s %s@%s gerrit ls-projects --has-acl-for \'%s\ -\ Maintainers\' --type ALL | grep scm/acls/domain_" % (server.port, server.account, server.url, name.replace(' ', '\ ')), shell = True).strip()
+
+def apply_git_trees(desc_list, server, cur_file):
+    for i in range(len(desc_list)):
+        git = desc_list[i][0]
+        desc = desc_list[i][1].replace('\\n', '\\\r\\\n').replace('; ', '; \\\r\\\n').replace(' ', '\ ').replace('&', '\&')
+        domain_info = get_domain_info(desc_list[i][1].split(';')[0].split('Domain:')[1].strip(), server)
+
+        line_num = int(subprocess.check_output("grep -n %s %s" % (git, cur_file), shell = True).split(':')[0])
+        line_message = "G: " + git
+
+        ## set description
+        ret = os.system('ssh -p %s %s@%s gerrit set-project %s -d "%s"' % (server.port, server.account, server.url, git, desc))
+        if ret:
+            raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s description setting is failed." % git))
+        else:
+            print_message('OK', cur_file, line_num, line_message, 'apply_git_trees - description')
+
+        ## set domain
+        ret = os.system('ssh -p %s %s@%s gerrit set-project-parent %s --parent %s' % (server.port, server.account, server.url, git, domain_info))
+        if ret:
+            raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s can't assign to %s." % git, domain_info))
+        else:
+            print_message('OK', cur_file, line_num, line_message, 'apply_git_trees - domain')
+
+def apply_member_to_domain(cur_file, obj, line_num, line_message, cur_domain, server):
+    if obj[0] == '-':
+        opt = '-r'
+    elif obj[0] == '+':
+        opt = '-a'
+
+    group = cur_domain + ' - ' + group_list[obj[1]]
+    mgroup = group.replace(' ', '\ ').replace('&', '\&')
+    user = line_message.split('%s: ' % line_message[0])[1]
+#    if '<' in user:
+#        if user.split('<')[1].split('>')[0] == 'n/a':
+#            user = user.split('<')[0].strip() + ' ' + user.split('>')[1].strip()
+    muser = user.replace(' ', '\ ').replace('<', '\<').replace('>', '\>')
+
+    ret = os.system('ssh -p %s %s@%s gerrit set-members \"%s\" %s \"%s\"' % (server.port, server.account, server.url, mgroup, opt, muser))
+    if ret:
+        raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s isn't applied in %s." % (user, group)))
+    else:
+        print_message('OK', cur_file, line_num, line_message, 'apply_member_to_domain')
+
+def apply_to_each_system(cur_file, obj, line_num, line_message, cur_section, server):
+    if cur_file == 'domains':
+        apply_member_to_domain(cur_file, obj, line_num, line_message, cur_section, server)
+    elif cur_file == 'git-trees':
+        ## git-trees will be applied at once later.
+        changed_git_list.add(cur_section)
+
+def apply_each_object(server):
+    for cur_file in meta_info.keys():
+        for i in range(len(meta_info[cur_file])):
+            for j in range(len(meta_info[cur_file][i])):
+                if j > 3:
+                    obj = meta_info[cur_file][i][j]
+                    if len(obj) == 0:
+                        continue
+                    elif obj[0] == '+' or obj[0] == '-':
+                        line_num = int(meta_info[cur_file][i][3].split(',')[0]) + j - 4
+                        line_message = "%s" % obj[0].join(obj.split(obj[0])[1:len(obj)])
+
+                        if len(obj) > 1:
+                            cur_section = find_section(line_num, meta_info[cur_file][i][2]).strip().split('%s: ' % list(key_list[cur_file].keys())[0])[1]
+                            apply_to_each_system(cur_file, obj, line_num, line_message, cur_section, server)
+
+def apply_to_system(meta_files, readme_file, sdir, port, account, url):
+    init_info(meta_files, readme_file, sdir)
+
+    try:
+        apply_each_object(Server(port, account, url))
+
+        ## git descriptions are applied at once.
+        final_desc_list = get_desc_list(list(changed_git_list))
+        apply_git_trees(final_desc_list, Server(port, account, url), 'git-trees')
+
+    except SyntaxError, ret:
+        return ret
+
+    return 0
diff --git a/common/check_scm_meta_git.py b/common/check_scm_meta_git.py
new file mode 100644 (file)
index 0000000..32ae651
--- /dev/null
@@ -0,0 +1,300 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 Samsung
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU General Public License
+#    as published by the Free Software Foundation; version 2
+#    of the License.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+"""Check syntax and semantics if they are in system."""
+
+import os
+import subprocess
+import collections
+import git_diff_parse
+
+class Server:
+    def __init__(self, port, account, url):
+        self.port = port
+        self.account = account
+        self.url = url
+
+class SyntaxError(Exception):
+    def __init__(self, value):
+        self.value = value
+    def __str__(self):
+        return self.value
+
+def get_diff_info(dic):
+        obj_list = []
+
+        git_diff_parse.git_diff_parse(obj_list)
+        for i in range(len(obj_list)):
+                for j in range(len(meta_file_list)):
+                        if obj_list[i][1] == meta_file_list[j]:
+                                dic[meta_file_list[j]].append(obj_list[i][:])
+                                break
+
+def get_key_list(dic, readme_file):
+        with open('%s' % readme_file, 'r') as lines:
+                read_status = False
+                cur_file = ''
+                for line in lines:
+                        if line.split(':')[0] == 'Filename':
+                                cur_file = line.split(':')[1].split('"')[1]
+                if cur_file in meta_file_list:
+                                    read_status = True
+                                continue
+                        if read_status:
+                                if line.strip() == '':
+                                        read_status = False
+                                else:
+                    temp = line.strip().split(' ')
+                    if temp[len(temp) - 2] + ' ' + temp[len(temp) - 1] == 'Read Only':
+                        attr = 1
+                    else:
+                        attr = 0
+                                        dic[cur_file][line.strip()[0]] = attr
+
+def init_info(file_list, readme_file, sdir):
+    global meta_file_list
+    global meta_info
+    global key_list
+    global scripts_dir
+
+    meta_file_list = []
+    meta_info = {}
+    key_list = {}
+    scripts_dir = sdir
+
+    for i in range(len(file_list)):
+        meta_file_list.append(file_list[i])
+        meta_info[file_list[i]] = []
+        key_list[file_list[i]] = collections.OrderedDict()
+
+    get_diff_info(meta_info)
+    get_key_list(key_list, readme_file)
+
+    global group_list
+    global git_domain
+    global domain_list
+
+    group_list = {'A' : 'Architects', 'M' : 'Maintainers', 'I' : 'Integrators', 'R' : 'Reviewers'}
+    git_domain = {}
+    domain_list = subprocess.check_output("cat domains | grep D:", shell = True).split('\n')
+
+def print_message(status, fn, ln, lm, comment):
+    if status == 'OK':
+        print("[%s, %d, OK] %s - %s" % (fn, ln, lm, comment))
+    else:
+        print("[%s, %d, Error] %s - %s" % (fn, ln, lm, comment))
+        return "[%s, %d, Error] %s - %s" % (fn, ln, lm, comment)
+
+def find_section(line_num, index):
+        return subprocess.check_output('%s/check_section.sh %d %s' % (scripts_dir, line_num, index), shell = True)
+
+def check_syntax(cur_file, obj, line_num, line_message):
+    if obj[0] == '+':
+        if len(obj) == 1:
+            next_line = subprocess.check_output('head -%d %s | tail -1' % (line_num + 1, cur_file), shell = True).strip()
+            if next_line == '' or next_line[0] == list(key_list[cur_file].keys())[0]:
+                print_message('OK', cur_file, line_num, line_message, 'check_syntax')
+            else:
+                raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "Next line has to be new section.\n[%s, %d, Error] %s" % (cur_file, line_num + 1, next_line)))
+        elif 1 < len(obj) < 4:
+            raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "Syntax is wrong."))
+        else:
+            prev_line = subprocess.check_output('head -%d %s | tail -1' % (line_num - 1, cur_file), shell = True).strip()
+            if prev_line == '':
+                raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "New section has to be %s in %s.\n[%s, %d, Error] %s" % (list(key_list[cur_file].keys())[0], cur_file, cur_file, line_num - 1, prev_line)))
+            else:
+                cur_key = obj[1] + obj[2] + obj[3]
+                if cur_key == cur_key[0] + ': ':
+                    if cur_key[0] in key_list[cur_file].keys():
+                        print_message('OK', cur_file, line_num, line_message, 'check_syntax')
+                    else:
+                        raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "\'%s\' is invalid key in this file." % cur_key[0]))
+                else:
+                    raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "Syntax is wrong."))
+    elif obj[0] == '-' and len(obj) == 1:
+        next_line = subprocess.check_output('head -%d %s | tail -1' % (line_num + 1, cur_file), shell = True).strip()
+        prev_line = subprocess.check_output('head -%d %s | tail -1' % (line_num - 1, cur_file), shell = True).strip()
+        if next_line and prev_line:
+            raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "New section has to be %s in %s." % (list(key_list[cur_file].keys())[0], cur_file)))
+        else:
+            print_message('OK', cur_file, line_num, line_message, 'check_syntax')
+    else:
+        print_message('OK', cur_file, line_num, line_message, 'check_syntax : Don\'t be checked.')
+
+def check_restriction(cur_file, obj, line_num, line_message):
+    cur_key = obj[1]
+
+    if key_list[cur_file][cur_key] == 1:
+        raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "Key \'%s\' in file \'%s\' is read-only." % (cur_key, cur_file)))
+    else:
+        print_message('OK', cur_file, line_num, line_message, 'check_restriction')
+
+def check_group(cur_file, obj, line_num, line_message, cur_domain, server):
+    group = cur_domain + ' - ' + group_list[obj[1]]
+    ret = os.system('ssh -p %s %s@%s gerrit ls-groups | grep -xq \"%s\"' % (server.port, server.account, server.url, group.replace(' ', '\ ')))
+    if ret:
+        raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s group doesn't exist." % group))
+    else:
+        print_message('OK', cur_file, line_num, line_message, 'check_group')
+
+def check_git_domain(cur_file, obj, line_num, line_message, cur_git):
+    if obj[0] == '+':
+        ret = 1
+        for i in range(len(domain_list)):
+            if domain_list[i] == line_message:
+                ret = 0
+                break
+        if ret:
+            raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s domain doesn't exist." % line_message.split('D: ')[1]))
+        else:
+            print_message('OK', cur_file, line_num, line_message, 'check_git_domain')
+
+    if cur_git in git_domain:
+        git_domain[cur_git].append([line_num, line_message])
+    else:
+        git_domain[cur_git] = [[line_num, line_message]]
+
+def is_email(name):
+    ret = ''
+
+    if '<' and '>' in name:
+        email = name.split('<')
+        last_index = len(email) - 1
+        email = email[last_index].split('>')[0]
+        if '@' in email:
+            ret = email
+    return ret
+
+def is_int(s):
+    try:
+        int(s)
+        return True
+    except ValueError:
+        return False
+
+def is_account_id(name):
+    ret = 0
+
+    if '(' and ')' in name:
+        account_id = name.split('(')
+        last_index = len(account_id) - 1
+        account_id = account_id[last_index].split(')')[0]
+        if is_int(account_id):
+            ret = account_id
+    return ret
+
+def check_account(name, server):
+    account_id_list = []
+
+    email_query = ''
+    email = is_email(name)
+    if email:
+        email_query = "and preferred_email=\\\'%s\\\'" % email
+
+    account_id_query = ''
+    account_id = is_account_id(name)
+    if account_id:
+        account_id_query = "and account_id=\\\'%s\\\'" % account_id
+
+    if email:
+        full_name = name.split('<%s>' % email)[0].strip()
+    elif account_id:
+        full_name = name.split('(%s)' % account_id)[0].strip()
+    else:
+        full_name = name.strip()
+
+    query = "select account_id from accounts where full_name=\\\'%s\\\' %s %s" % (full_name, email_query, account_id_query)
+    res = subprocess.check_output('ssh -p %s %s@%s gerrit gsql -c \"%s\"' % (server.port, server.account, server.url, query.replace(' ', '\ ')), shell = True).split('\n')
+
+    for i in range(len(res) - 2):
+        if i > 1:
+            account_id_list.append(res[i].strip())
+
+    return account_id_list
+
+def check_user(cur_file, obj, line_num, line_message, server):
+    account = obj.split('%s%s: ' % (obj[0], obj[1]))[1]
+    account_id_list = check_account(account, server)
+    if len(account_id_list) == 0:
+        raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s is wrong. Check full name or email again." % account))
+    elif len(account_id_list) == 1:
+        print_message('OK', cur_file, line_num, line_message, 'check_user')
+    else:
+        raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s is ambiguous. Specify account_id %s." % (account, account_id_list)))
+
+def check_user_in_group(cur_file, obj, line_num, line_message, cur_domain, server):
+    group = cur_domain + ' - ' + group_list[obj[1]]
+    account = obj.split('%s%s: ' % (obj[0], obj[1]))[1]
+    ret = os.system('ssh -p %s %s@%s gerrit ls-groups --user \"%s\" | grep -xq \"%s\"' % (server.port, server.account, server.url, account.replace(' ', '\ '), group.replace(' ', '\ ')))
+    if ret:
+        print_message('OK', cur_file, line_num, line_message, 'check_user_in_group')
+    else:
+        raise SyntaxError(print_message('Error', cur_file, line_num, line_message, "%s is already in %s." % (account, group)))
+
+def check_semantics(cur_file, obj, line_num, line_message, cur_section, server):
+    check_restriction(cur_file, obj, line_num, line_message)
+
+    if cur_file == 'domains':
+        if obj[1] in group_list:
+            if obj[0] == '+':
+                check_group(cur_file, obj, line_num, line_message, cur_section, server)
+                check_user(cur_file, obj, line_num, line_message, server)
+                check_user_in_group(cur_file, obj, line_num, line_message, cur_section, server)
+    elif cur_file == 'git-trees':
+        if obj[1] == 'D':
+            check_git_domain(cur_file, obj, line_num, line_message, cur_section)
+        if obj[1] == 'O':
+            check_user(cur_file, obj, line_num, line_message, server)
+
+def check_each_object(server):
+    for cur_file in meta_info.keys():
+        for i in range(len(meta_info[cur_file])):
+            for j in range(len(meta_info[cur_file][i])):
+                if j > 3:
+                    obj = meta_info[cur_file][i][j]
+                    if len(obj) == 0:
+                        continue
+                    elif obj[0] == '+' or obj[0] == '-':
+                        line_num = int(meta_info[cur_file][i][3].split(',')[0]) + j - 4
+                        line_message = "%s" % obj[0].join(obj.split(obj[0])[1:len(obj)])
+
+                        check_syntax(cur_file, obj, line_num, line_message)
+
+                        if len(obj) > 1:
+                            cur_section = find_section(line_num, meta_info[cur_file][i][2]).strip().split('%s: ' % list(key_list[cur_file].keys())[0])[1]
+                            check_semantics(cur_file, obj, line_num, line_message, cur_section, server)
+
+def check_domain_edit():
+    for git_project in git_domain.keys():
+        if len(git_domain[git_project]) != 2:
+            raise SyntaxError(print_message('Error', 'git-trees', git_domain[git_project][0][0], git_domain[git_project][0][1], "Domain(Subdomain) can't be added or removed."))
+        else:
+            print_message('OK', 'git-trees', git_domain[git_project][0][0], git_domain[git_project][0][1], 'check_domain_edit')
+
+def check_patchset_is_valid(meta_files, readme_file, sdir, port, account, url):
+
+    init_info(meta_files, readme_file, sdir)
+
+    try:
+        check_each_object(Server(port, account, url))
+        check_domain_edit()
+
+    except SyntaxError, ret:
+        return ret
+
+    return 0
diff --git a/common/git_diff_parse.py b/common/git_diff_parse.py
new file mode 100644 (file)
index 0000000..e5da666
--- /dev/null
@@ -0,0 +1,88 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 Samsung
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU General Public License
+#    as published by the Free Software Foundation; version 2
+#    of the License.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+"""Parse different data based on git show command"""
+
+import os
+
+def git_diff_parse(obj_list):
+    diff_file = ".diff.tmp"
+    os.system('git show > %s' % diff_file)
+
+    with open('%s' % diff_file, 'r') as diff_list:
+        before_info = []
+        after_info = []
+
+        diff_status = False
+
+        for lines in diff_list:
+            line = lines.rstrip().split(' ')
+
+            if line[0] == 'diff':
+                if len(before_info):
+                    obj_list.append(before_info[:])
+                    before_info = []
+                if len(after_info):
+                    obj_list.append(after_info[:])
+                    after_info = []
+
+                before_info.append('-')
+                before_info.append("a/".join(line[2].split('a/')[1:len(line[2])]))
+                after_info.append('+')
+                after_info.append("b/".join(line[3].split('b/')[1:len(line[3])]))
+
+                diff_status = False
+
+            elif line[0] == 'index':
+                indexes = line[1].split('..')
+
+                before_info.append(indexes[0])
+                after_info.append(indexes[1])
+
+            elif line[0] == '@@':
+                if len(after_info) > 3 or len(before_info) > 3:
+                    obj_list.append(before_info[:])
+                    obj_list.append(after_info[:])
+
+                    before_info = [before_info[0], before_info[1], before_info[2]]
+                    after_info = [after_info[0], after_info[1], after_info[2]]
+
+                diff_status = True
+
+                before_info.append("-".join(line[1].split('-')[1:len(line[1])]))
+                after_info.append("+".join(line[2].split('+')[1:len(line[2])]))
+
+            else:
+                if diff_status:
+                    if lines[0] == '-':
+                        before_info.append(lines.strip())
+
+                    elif lines[0] == '+':
+                        after_info.append(lines.strip())
+
+                    else:
+                        before_info.append(lines.strip())
+                        after_info.append(lines.strip())
+
+        if len(before_info):
+            obj_list.append(before_info[:])
+
+        if len(after_info):
+            obj_list.append(after_info[:])
+
+    os.system('rm -f "%s"' % diff_file)
diff --git a/job_check_scm_meta_git.py b/job_check_scm_meta_git.py
new file mode 100755 (executable)
index 0000000..1f798a2
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2016 Samsung
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU General Public License
+#    as published by the Free Software Foundation; version 2
+#    of the License.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+"""This job will clone scm/meta/git project, and update it to gerrit system"""
+
+import sys
+import os
+from common.gerrit import Gerrit, get_gerrit_event
+from common.git import fetch_change
+from common.check_scm_meta_git import check_patchset_is_valid
+from common.apply_scm_meta_git import apply_to_system
+
+GERRIT_PROJECT = os.getenv('GERRIT_PROJECT')
+WORKSPACE = os.getenv('WORKSPACE')
+GERRIT_HOSTNAME = os.getenv('GERRIT_HOSTNAME')
+GERRIT_USERNAME = os.getenv('GERRIT_USERNAME')
+GERRIT_SSHPORT = os.getenv('GERRIT_SSHPORT')
+GERRIT_SILENT_MODE = int(os.getenv('GERRIT_SILENT_MODE'))
+
+#meta_file_list = ['domains', 'git-trees', 'branches']
+meta_file_list = ['domains', 'git-trees']
+readme_file = 'README.txt'
+scripts_path  = os.path.dirname(os.path.abspath(__file__)) + '/scripts'
+
+def check_scm_meta_git(gerrit, events):
+    ret = check_patchset_is_valid(meta_file_list, readme_file, scripts_path, gerrit.port, gerrit.username, gerrit.host)
+    if ret:
+        gerrit.review(commit = events['patchset_revision'], message = str(ret), verified = -1)
+        return 1
+    else:
+        gerrit.review(commit = events['patchset_revision'], message = "SCM syntax & semantic check OK.", verified = 1)
+        return 0
+
+def update_system(gerrit, events):
+    ret = apply_to_system(meta_file_list, readme_file, scripts_path, gerrit.port, gerrit.username, gerrit.host)
+        if ret:
+                gerrit.review(commit = events['patchset_revision'], message = "There is something wrong. Contact to %s" % events['event_account_email'])
+                return 1
+        else:
+                gerrit.review(commit = events['patchset_revision'], message = "Complete to apply to system.")
+                return 0
+
+def main():
+    events = get_gerrit_event()
+    print(events)
+
+    #fecth and checkout change
+    fetch_change(GERRIT_PROJECT, WORKSPACE, events['refspec'])
+
+    gerrit = Gerrit(GERRIT_HOSTNAME, GERRIT_USERNAME, GERRIT_SSHPORT, GERRIT_SILENT_MODE)
+
+    if events['event_type'] == 'patchset-created':
+        return check_scm_meta_git(gerrit, events)
+    elif events['event_type'] == 'change-merged':
+        return update_system(gerrit, events)
+    else:
+        return 1
+
+if __name__ == '__main__':
+    sys.exit(main())
diff --git a/scripts/check_section.sh b/scripts/check_section.sh
new file mode 100755 (executable)
index 0000000..0d586c4
--- /dev/null
@@ -0,0 +1,43 @@
+#!/bin/bash
+
+# Copyright (C) 2016 Samsung
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU General Public License
+#    as published by the Free Software Foundation; version 2
+#    of the License.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+"""Search first line in current paragraph"""
+
+
+CNT=$1
+INDEX=$2
+
+FILE=file.tmp
+
+git cat-file -p $INDEX > $FILE
+
+while [ 1 ]
+do
+        CHK=`head -$CNT $FILE | tail -1`
+
+    if [ "$CHK" = "" ] || [ $CNT -eq 0 ]; then
+        RET=`head -$((CNT + 1)) $FILE | tail -1`
+        if [ "$RET" != "" ]; then
+            echo $RET
+            break;
+        fi
+        fi
+        CNT=$((CNT - 1))
+done
+
+rm -f $FILE
diff --git a/scripts/get_git_desc_info.sh b/scripts/get_git_desc_info.sh
new file mode 100755 (executable)
index 0000000..5502c02
--- /dev/null
@@ -0,0 +1,42 @@
+#!/bin/bash
+
+# Copyright (C) 2016 Samsung
+#
+#    This program is free software; you can redistribute it and/or
+#    modify it under the terms of the GNU General Public License
+#    as published by the Free Software Foundation; version 2
+#    of the License.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program; if not, write to the Free Software
+#    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+#
+"""Search some data in git-trees file"""
+
+
+GIT=$1
+
+FILE="git-trees"
+LAST_LINE_NUM=`wc -l $FILE | awk -F ' ' '{print $1}'`
+
+CNT=`grep -xn "G:\ $GIT" $FILE | awk -F ':' '{print $1}'`
+
+RET=""
+
+while [ 1 ]
+do
+    CHK=`head -$CNT $FILE | tail -1`
+    if [ "$CHK" = "" ] || [ $CNT -eq $((LAST_LINE_NUM + 1)) ]; then
+        echo $RET
+        break;
+    fi
+    if [ "${CHK:$i:1}" = "D" ] || [ "${CHK:$i:1}" = "O" ] || [ "${CHK:$i:1}" = "L" ] || [ "${CHK:$i:1}" = "C" ]; then
+                RET="$RET$CHK;"
+        fi
+    CNT=$((CNT + 1))
+done