def get_modules_changed(path, ref='HEAD'):
    '''Get modules changed from git diff-index {ref}
    :param path: String path of git repo
    :param ref: branch or remote/branch or sha to compare
    :return: List of paths of modules changed
    '''
    git_run_obj = GitRun(os.path.join(path, '.git'))
    if ref != 'HEAD':
        fetch_ref = ref
        if ':' not in fetch_ref:
            # to force create branch
            fetch_ref += ':' + fetch_ref
        git_run_obj.run(['fetch'] + fetch_ref.split('/', 1))
    items_changed = git_run_obj.get_items_changed(ref)
    folders_changed = set([
        item_changed.split('/')[0]
        for item_changed in items_changed
        if '/' in item_changed]
    )
    modules = set(get_modules(path))
    modules_changed = list(modules & folders_changed)
    modules_changed_path = [
        os.path.join(path, module_changed)
        for module_changed in modules_changed]
    return modules_changed_path
Ejemplo n.º 2
0
def get_modules_changed(path, ref='HEAD'):
    '''Get modules changed from git diff-index {ref}
    :param path: String path of git repo
    :param ref: branch or remote/branch or sha to compare
    :return: List of paths of modules changed
    '''
    git_run_obj = GitRun(os.path.join(path, '.git'))
    if ref != 'HEAD':
        fetch_ref = ref
        if ':' not in fetch_ref:
            # to force create branch
            fetch_ref += ':' + fetch_ref
        git_run_obj.run(['fetch'] + fetch_ref.split('/', 1))
    items_changed = git_run_obj.get_items_changed(ref)
    folders_changed = set([
        item_changed.split('/')[0]
        for item_changed in items_changed
        if '/' in item_changed]
    )
    modules = set(get_modules(path))
    modules_changed = list(modules & folders_changed)
    modules_changed_path = [
        os.path.join(path, module_changed)
        for module_changed in modules_changed]
    return modules_changed_path
Ejemplo n.º 3
0
class GitRmAllLog(object):

    def __init__(self, git_url,
                 root_path=None):
        self.git_url = git_url
        if root_path is None:
            root_path = gettempdir()
        else:
            root_path = os.path.expandvars(
                os.path.expanduser(root_path)
            )
        self.git_run_obj = GitRun(git_url, None)
        self.git_run_obj.path = os.path.join(
            root_path,
            self.git_run_obj.owner,
            self.git_run_obj.repo
        )

    def rm_all_log(self, items):
        self.git_run_obj.update()
        refs = self.git_run_obj.get_ref_data(['refs/heads']).keys()
        for ref in refs:
            self.git_run_obj.checkout_bare(ref)
            self.git_run_obj.run([
                "filter-branch", "-f", "--tree-filter",
                "rm -rf %s" % items, "HEAD"
            ])
class TravisWeblateUpdate(object):

    GIT_COMMIT_INFO = {
        'author':
        'Weblate bot <weblate@bot>',
        'message':
        '[REF] i18n: Updating translation terms from weblate '
        '[ci skip]'
    }

    def __init__(self):
        self._git = GitRun(os.path.join(os.getcwd(), '.git'), True)
        self.branch = os.environ.get("TRAVIS_BRANCH",
                                     self._git.get_branch_name())
        remote = self._git.run(["ls-remote", "--get-url", "origin"])
        name = remote.replace(':', '/')
        name = re.sub('.+@', '', name)
        name = re.sub('.git$', '', name)
        name = re.sub('^https://', '', name)
        name = re.sub('^http://', '', name)
        match = re.search(r'(?P<host>[^/]+)/(?P<owner>[^/]+)/(?P<repo>[^/]+)',
                          name)
        if match:
            name = ("%(host)s:%(owner)s/%(repo)s (%(branch)s)" %
                    dict(match.groupdict(), branch=self.branch))
        self.repo_name = name
        self.wl_api = WeblateApi()
        self.gh_api = GitHubApi()
        self._travis_home = os.environ.get("HOME", "~/")
        self._travis_build_dir = os.environ.get("TRAVIS_BUILD_DIR", "../..")
        self._odoo_version = os.environ.get("VERSION")
        self._odoo_branch = os.environ.get("ODOO_BRANCH")
        self._langs = (parse_list(os.environ.get("LANG_ALLOWED"))
                       if os.environ.get("LANG_ALLOWED", False) else [])
        self._odoo_full = os.environ.get("ODOO_REPO", "odoo/odoo")
        self._server_path = get_server_path(
            self._odoo_full, (self._odoo_branch or self._odoo_version),
            self._travis_home)
        self._addons_path = get_addons_path(self._travis_home,
                                            self._travis_build_dir,
                                            self._server_path)
        self._database = os.environ.get('MQT_TEST_DB', 'openerp_test')
        self._connection_context = context_mapping.get(self._odoo_version,
                                                       Odoo10Context)
        self._apply_patch_odoo()
        self._get_modules_installed()

    def _check(self):
        self.wl_api._check()
        self.gh_api._check()

    def _apply_patch_odoo(self):
        """This patch is necessary because the weblate does not check which
        word and the translated are the same to use it in its percentage of
        translated"""
        for base in ('odoo', 'openerp'):
            p_file = os.path.join(self._server_path, base,
                                  os.path.join('tools', 'translate.py'))
            if os.path.isfile(p_file):
                sed = [
                    "sed", "-i", "-e",
                    r"s/translation'] = src/translation'] = ''/g", p_file
                ]
                print " ".join(sed)
                subprocess.call(sed)
            p_file = os.path.join(
                self._server_path, base,
                os.path.join('addons', 'base', 'ir', 'ir_translation.py'))
            if os.path.isfile(p_file):
                sed = [
                    "sed", "-i", "-e",
                    r"s/if\snot\strans_dict\['value']:/if False:/g", p_file
                ]
                print " ".join(sed)
                subprocess.call(sed)

    def _get_modules_installed(self):
        self._installed_modules = []
        modules_found = []
        for name in ('__openerp__.py', '__manifest__.py'):
            modules = glob.glob('%s/**/%s' % (self._travis_build_dir, name))
            if not modules:
                continue
            modules_found.extend(
                [os.path.dirname(module).split('/')[-1] for module in modules])
        with self._connection_context(self._server_path, self._addons_path,
                                      self._database) as odoo_context:
            odoo_context.cr.execute(
                "select name from ir_module_module"
                " where state = 'installed' and "
                "name in %s", (tuple(modules_found), ))
            modules = odoo_context.cr.dictfetchall()
            self._installed_modules = [module['name'] for module in modules]

    def _generate_odoo_po_files(self, component):
        generated = False
        with self._connection_context(self._server_path, self._addons_path,
                                      self._database) as odoo_context:
            module = component['name']
            if module not in self._installed_modules:
                return generated
            print("\n", yellow("Obtaining POT file for %s" % module))
            i18n_folder = os.path.join(self._travis_build_dir, module, 'i18n')
            if not os.path.isdir(i18n_folder):
                os.makedirs(i18n_folder)
            # Put git add for letting known git which translations to update
            po_files = glob.glob(os.path.join(i18n_folder, '*.po'))
            for lang in self._langs:
                if os.path.isfile(os.path.join(i18n_folder, lang + '.po')):
                    continue
                po_content = odoo_context.get_pot_contents(module, lang)
                if not po_content:
                    continue
                with open(os.path.join(i18n_folder, lang + '.po'), 'wb')\
                        as f_po:
                    f_po.write(po_content)
            for po_file_name in po_files:
                lang = os.path.basename(os.path.splitext(po_file_name)[0])
                if self._langs and lang not in self._langs:
                    # Limit just allowed languages if is defined
                    continue
                po_file_path = os.path.join(i18n_folder, po_file_name)
                with open(po_file_path, 'r') as f_po:
                    odoo_context.load_po(f_po, lang)
                new_content = odoo_context.get_pot_contents(module, lang)
                if not new_content:
                    continue
                with open(po_file_path, 'wb') as f_po:
                    f_po.write(new_content)
                diff = self._git.run(["diff", "HEAD", po_file_path])
                if diff.count('msgstr') == 1:
                    self._git.run(["checkout", po_file_path])
            if self._git.run(["add", "-v"] + po_files):
                generated = True
        return generated

    def _check_conflict(self, component):
        status = self._git.run(["status"])
        conflicts = [
            item for item in status.split('\n')
            if (item.startswith('\tboth modified')
                and component['filemask'].replace('/*.po', '') in item)
        ]
        if conflicts:
            self._register_pull_request(component, status)
            return True
        return False

    def _register_pull_request(self, component, status):
        branch_name = 'conflict-%s-weblate' % self.branch
        self._git.run(["add", component['filemask']])
        self._git.run([
            "commit", "--no-verify", "--author='Weblate bot <weblate@bot>'",
            "-m", "[REF] i18n: Conflict on the daily cron", "-m", status
        ])
        self._git.run(["branch", "-m", branch_name])
        self._git.run(["push", "-f", "origin", branch_name])
        pull = self.gh_api.create_pull_request({
            'title':
            '[REF] i18n: Conflict on the daily cron',
            'head':
            '%s:%s' %
            (self.repo_name.split('/')[0].split(':')[1], branch_name),
            'base':
            self.branch,
            'body':
            status
        })
        self._git.run(
            ["checkout", "-qb", self.branch,
             "origin/%s" % self.branch])
        self._git.run(["branch", "-D", branch_name])
        print yellow("The pull request register is: %s" % pull['html_url'])

    def _commit_weblate(self, first_commit=False):
        if ('nothing to commit, working tree clean'
                in self._git.run(["status"])):
            return first_commit
        if first_commit:
            self._git.run(["commit", "--no-verify", "--amend", "--no-edit"])
        else:
            self._git.run([
                "commit", "--no-verify",
                "--author='%s'" % self.GIT_COMMIT_INFO['author'], "-m",
                self.GIT_COMMIT_INFO['message']
            ])
            first_commit = True
        return first_commit

    def _push_git_repository(self):
        po_files = self._git.run(
            ["show", "--format=format:'%H'", "--name-only"]).split('\n')
        if not len(po_files) > 1:
            return False
        commit = self.gh_api.create_commit(self.GIT_COMMIT_INFO['message'],
                                           self.branch, po_files[1:])
        if commit:
            for component in self.wl_api.components:
                self.wl_api.component_repository(component, 'reset')
                self.wl_api.component_repository(component, 'pull')
        return commit

    def update(self):
        self._check()
        self.wl_api.load_project(self.repo_name, self.branch)
        if not self.wl_api.components:
            print yellow("No component found for %s" % self.repo_name)
            return 1
        with self.wl_api.component_lock():
            self._git.run(["fetch", "origin"])
            first_commit = False
            for component in self.wl_api.components:
                print yellow("Component %s" % component['slug'])
                name = '%s-wl' % component['slug']
                remote = (self.wl_api.host.replace('api', 'git') + '/' +
                          self.wl_api.project['slug'] + '/' +
                          component['slug'])
                self._git.run([
                    "checkout", "-qb", self.branch,
                    "origin/%s" % self.branch
                ])
                self.wl_api.component_repository(component, 'pull')
                self._git.run(["remote", "add", name, remote])
                self._git.run(["fetch", name])
                if self._generate_odoo_po_files(component):
                    first_commit = self._commit_weblate(first_commit)
                self._git.run([
                    "merge", "--squash", "-s", "recursive", "-X", "ours",
                    "%s/%s" % (name, self.branch)
                ])
                self._git.run(["remote", "remove", name])
                if self._check_conflict(component):
                    break
                if (component['filemask'].replace('/*.po', '')
                        in self._git.run(["status"])):
                    self._git.run(["add", component['filemask']])
                    first_commit = self._commit_weblate(first_commit)
                if self._check_conflict(component):
                    break
                first_commit = self._commit_weblate(first_commit)
            if not self._push_git_repository():
                return 1
        return 0
class TravisWeblateUpdate(object):

    GIT_COMMIT_INFO = {
        'author': 'Weblate bot <weblate@bot>',
        'message': '[REF] i18n: Updating translation terms from weblate '
                   '[ci skip]'
    }

    def __init__(self):
        self._git = GitRun(os.path.join(os.getcwd(), '.git'), True)
        self.branch = os.environ.get("TRAVIS_BRANCH",
                                     self._git.get_branch_name())
        remote = self._git.run(["ls-remote", "--get-url", "origin"])
        name = remote.replace(':', '/')
        name = re.sub('.+@', '', name)
        name = re.sub('.git$', '', name)
        name = re.sub('^https://', '', name)
        name = re.sub('^http://', '', name)
        match = re.search(
            r'(?P<host>[^/]+)/(?P<owner>[^/]+)/(?P<repo>[^/]+)', name)
        if match:
            name = ("%(host)s:%(owner)s/%(repo)s (%(branch)s)" %
                    dict(match.groupdict(), branch=self.branch))
        self.repo_name = name
        self.wl_api = WeblateApi()
        self.gh_api = GitHubApi()
        self._travis_home = os.environ.get("HOME", "~/")
        self._travis_build_dir = os.environ.get("TRAVIS_BUILD_DIR", "../..")
        self._odoo_version = os.environ.get("VERSION")
        self._odoo_branch = os.environ.get("ODOO_BRANCH")
        self._langs = (parse_list(os.environ.get("LANG_ALLOWED")) if
                       os.environ.get("LANG_ALLOWED", False) else [])
        self._odoo_full = os.environ.get("ODOO_REPO", "odoo/odoo")
        self._server_path = get_server_path(self._odoo_full,
                                            (self._odoo_branch or
                                             self._odoo_version),
                                            self._travis_home)
        self._addons_path = get_addons_path(self._travis_home,
                                            self._travis_build_dir,
                                            self._server_path)
        self._database = os.environ.get('MQT_TEST_DB', 'openerp_test')
        self._connection_context = context_mapping.get(
            self._odoo_version, Odoo10Context)
        self._apply_patch_odoo()
        self._get_modules_installed()

    def _check(self):
        self.wl_api._check()
        self.gh_api._check()

    def _apply_patch_odoo(self):
        """This patch is necessary because the weblate does not check which
        word and the translated are the same to use it in its percentage of
        translated"""
        for base in ('odoo', 'openerp'):
            p_file = os.path.join(self._server_path, base,
                                  os.path.join('tools', 'translate.py'))
            if os.path.isfile(p_file):
                sed = ["sed", "-i", "-e",
                       r"s/translation'] = src/translation'] = ''/g", p_file]
                print " ".join(sed)
                subprocess.call(sed)
            p_file = os.path.join(self._server_path, base,
                                  os.path.join('addons', 'base', 'ir',
                                               'ir_translation.py'))
            if os.path.isfile(p_file):
                sed = ["sed", "-i", "-e",
                       r"s/if\snot\strans_dict\['value']:/if False:/g", p_file]
                print " ".join(sed)
                subprocess.call(sed)

    def _get_modules_installed(self):
        self._installed_modules = []
        modules_found = []
        for name in ('__openerp__.py', '__manifest__.py'):
            modules = glob.glob('%s/**/%s' % (self._travis_build_dir, name))
            if not modules:
                continue
            modules_found.extend([
                os.path.dirname(module).split('/')[-1] for module in
                modules])
        with self._connection_context(self._server_path, self._addons_path,
                                      self._database) as odoo_context:
            odoo_context.cr.execute("select name from ir_module_module"
                                    " where state = 'installed' and "
                                    "name in %s", (tuple(modules_found),))
            modules = odoo_context.cr.dictfetchall()
            self._installed_modules = [module['name'] for module in modules]

    def _generate_odoo_po_files(self, module, only_installed=True):
        generated = False
        with self._connection_context(self._server_path, self._addons_path,
                                      self._database) as odoo_context:
            if only_installed and module not in self._installed_modules:
                return generated
            print("\n", yellow("Obtaining POT file for %s" % module))
            i18n_folder = os.path.join(self._travis_build_dir, module, 'i18n')
            if not os.path.isdir(i18n_folder):
                os.makedirs(i18n_folder)
            # Put git add for letting known git which translations to update
            po_files = glob.glob(os.path.join(i18n_folder, '*.po'))
            for lang in self._langs:
                if os.path.isfile(os.path.join(i18n_folder, lang + '.po')):
                    continue
                po_content = odoo_context.get_pot_contents(module, lang)
                if not po_content:
                    continue
                with open(os.path.join(i18n_folder, lang + '.po'), 'wb')\
                        as f_po:
                    f_po.write(po_content)
                    if self._git.run(["add", "-v", f_po.name]):
                        generated = True
            for po_file_name in po_files:
                lang = os.path.basename(os.path.splitext(po_file_name)[0])
                if self._langs and lang not in self._langs:
                    # Limit just allowed languages if is defined
                    continue
                po_file_path = os.path.join(i18n_folder, po_file_name)
                with open(po_file_path, 'r') as f_po:
                    odoo_context.load_po(f_po, lang)
                new_content = odoo_context.get_pot_contents(module, lang)
                if not new_content:
                    continue
                with open(po_file_path, 'wb') as f_po:
                    f_po.write(new_content)
                diff = self._git.run(["diff", "HEAD", po_file_path])
                if diff.count('msgstr') == 1:
                    self._git.run(["checkout", po_file_path])
            if self._git.run(["add", "-v"] + po_files):
                generated = True
        return generated

    def _check_conflict(self, component):
        status = self._git.run(["status"])
        conflicts = [item for item in status.split('\n')
                     if (item.startswith('\tboth modified') and
                         component['filemask'].replace('/*.po', '') in item)]
        if conflicts:
            self._register_pull_request(component, status)
            return True
        return False

    def _register_pull_request(self, component, status):
        branch_name = 'conflict-%s-weblate' % self.branch
        self._git.run(["add", component['filemask']])
        self._git.run(["commit", "--no-verify",
                       "--author='Weblate bot <weblate@bot>'",
                       "-m", "[REF] i18n: Conflict on the daily cron",
                       "-m", status])
        self._git.run(["branch", "-m", branch_name])
        self._git.run(["push", "-f", "origin", branch_name])
        pull = self.gh_api.create_pull_request({
            'title': '[REF] i18n: Conflict on the daily cron',
            'head': '%s:%s' % (self.repo_name.split('/')[0].split(':')[1],
                               branch_name),
            'base': self.branch,
            'body': status
        })
        self._git.run(["checkout", "-qb", self.branch,
                       "origin/%s" % self.branch])
        self._git.run(["branch", "-D", branch_name])
        print yellow("The pull request register is: %s" % pull['html_url'])

    def _commit_weblate(self, first_commit=False):
        if ('nothing to commit, working tree clean'
                in self._git.run(["status"])):
            return first_commit
        if first_commit:
            self._git.run(["commit", "--no-verify", "--amend",
                           "--no-edit"])
        else:
            self._git.run(["commit", "--no-verify",
                           "--author='%s'" % self.GIT_COMMIT_INFO['author'],
                           "-m", self.GIT_COMMIT_INFO['message']])
            first_commit = True
        return first_commit

    def _push_git_repository(self):
        po_files = self._git.run(["show", "--format=format:'%H'",
                                  "--name-only"]).split('\n')
        if not len(po_files) > 1:
            return False
        commit = self.gh_api.create_commit(self.GIT_COMMIT_INFO['message'],
                                           self.branch,
                                           po_files[1:])
        if commit:
            for component in self.wl_api.components:
                self.wl_api.component_repository(component, 'reset')
                self.wl_api.component_repository(component, 'pull')
        return commit

    def update(self):
        self._check()
        self.wl_api.load_project(self.repo_name, self.branch)
        with self.wl_api.component_lock():
            self._git.run(["fetch", "origin"])
            first_commit = False
            component = [item for item in self.wl_api.components
                         if item['git_export']]
            if len(component) > 1:
                print yellow("To many repository for this project %s" %
                             self.wl_api.project['name'])
                return 1
            remote = (self.wl_api.ssh + '/' + self.wl_api.project['slug'] +
                      '/' + component[0]['slug'])
            name = '%s-wl' % self.wl_api.project['slug']
            self._git.run(["remote", "add", name, remote])
            for component in self.wl_api.components:
                print yellow("Component %s" % component['slug'])
                self._git.run(["checkout", "-qb", self.branch,
                               "origin/%s" % self.branch])
                self.wl_api.component_repository(component, 'pull')
                self._git.run(["fetch", name])
                if self._generate_odoo_po_files(component['name']):
                    first_commit = self._commit_weblate(first_commit)
                self._git.run(["merge", "--squash", "-s", "recursive", "-X",
                               "ours", "%s/%s" % (name, self.branch)])
                if self._check_conflict(component):
                    break
                if (component['filemask'].replace('/*.po', '') in
                        self._git.run(["status"])):
                    self._git.run(["add", component['filemask']])
                    first_commit = self._commit_weblate(first_commit)
                if self._check_conflict(component):
                    break
                first_commit = self._commit_weblate(first_commit)
            self._git.run(["remote", "remove", name])
            modules_no_processed = [module for module in
                                    self._installed_modules if module not in
                                    [comp['name'] for comp in
                                     self.wl_api.components]]
            for component in modules_no_processed:
                if self._generate_odoo_po_files(component,
                                                only_installed=False):
                    first_commit = self._commit_weblate(first_commit)
            if not self._push_git_repository():
                return 1
        return 0
def translate_gitlab_env():
    """ This sets Travis CI's variables using GitLab CI's variables. This
        makes possible to run scripts which depend on Travis CI's variables
        when running under Gitlab CI.

         For documentation on these environment variables, please check:
        - Predefined environment variables on Travis CI:
          https://docs.travis-ci.com/user/environment-variables#Default-Environment-Variables
        - Predefined environment variables on GitLab CI:
          https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables
    """
    if not os.environ.get("GITLAB_CI"):
        return False
    build_dir = os.environ.get("CI_PROJECT_DIR", ".")
    git_run_obj = GitRun(repo_path=os.path.join(build_dir, ".git"))
    commit_message = git_run_obj.run(["log", "-1", "--pretty=%b"])
    head_branch = os.environ.get("CI_COMMIT_REF_NAME")
    # This is a guess
    target_branch = os.environ.get("VERSION")

    # Set environment variables
    os.environ.update({
        # Predefined values
        "TRAVIS": "true",
        "CONTINUOUS_INTEGRATION": "true",
        "HAS_JOSH_K_SEAL_OF_APPROVAL": "true",
        "RAILS_ENV": "test",
        "RACK_ENV": "test",
        "MERB_ENV": "test",
        "TRAVIS_ALLOW_FAILURE": "false",
        "TRAVIS_JOB_NUMBER": "1",
        "TRAVIS_TEST_RESULT": "0",
        "TRAVIS_COMMIT_RANGE": "unknown",
        # Dinamic values
        "TRAVIS_BRANCH": target_branch,
        "TRAVIS_COMMIT_MESSAGE": commit_message,
        "TRAVIS_OS_NAME": sys.platform,
        "TRAVIS_SUDO": "true" if getuser() == "root" else "false",
    })

# Set variables whose values are already directly set in other variables
    equivalent_vars = [
        ("TRAVIS_BUILD_DIR", "CI_PROJECT_DIR"),
        ("TRAVIS_BUILD_ID", "CI_BUILD_ID"),
        ("TRAVIS_BUILD_NUMBER", "CI_JOB_ID"),
        ("TRAVIS_COMMIT", "CI_COMMIT_SHA"),
        ("TRAVIS_EVENT_TYPE", "CI_PIPELINE_SOURCE"),
        ("TRAVIS_JOB_ID", "CI_JOB_ID"),
        ("TRAVIS_REPO_SLUG", "CI_PROJECT_PATH"),
        ("TRAVIS_BUILD_STAGE_NAME", "CI_BUILD_STAGE"),
    ]
    os.environ.update({
        travis_var: os.environ.get(gitlab_var)
        for travis_var, gitlab_var in equivalent_vars
        if gitlab_var in os.environ
    })

    # If within an MR
    is_mr = target_branch != head_branch
    if is_mr:
        os.environ.update({
            # there's no way to know the MR number. For more info, see:
            # https://gitlab.com/gitlab-org/gitlab-ce/issues/15280
            "TRAVIS_PULL_REQUEST": "unknown",
            "TRAVIS_PULL_REQUEST_BRANCH": head_branch,
            "TRAVIS_PULL_REQUEST_SHA": os.environ.get("CI_COMMIT_SHA"),
            "TRAVIS_PULL_REQUEST_SLUG": os.environ.get("CI_PROJECT_PATH"),
        })
    else:
        os.environ.update({
            "TRAVIS_PULL_REQUEST": "false",
            "TRAVIS_PULL_REQUEST_BRANCH": "",
            "TRAVIS_PULL_REQUEST_SHA": "",
            "TRAVIS_PULL_REQUEST_SLUG": "",
        })
    return True
def translate_gitlab_env():
    """ This sets Travis CI's variables using GitLab CI's variables. This
        makes possible to run scripts which depend on Travis CI's variables
        when running under Gitlab CI.

         For documentation on these environment variables, please check:
        - Predefined environment variables on Travis CI:
          https://docs.travis-ci.com/user/environment-variables#Default-Environment-Variables
        - Predefined environment variables on GitLab CI:
          https://docs.gitlab.com/ee/ci/variables/#predefined-variables-environment-variables
    """
    if not os.environ.get("GITLAB_CI"):
        return False
    build_dir = os.environ.get("CI_PROJECT_DIR", ".")
    git_run_obj = GitRun(repo_path=os.path.join(build_dir, ".git"))
    commit_message = git_run_obj.run(["log", "-1", "--pretty=%b"])
    head_branch = os.environ.get("CI_COMMIT_REF_NAME")
    # This is a guess
    target_branch = os.environ.get("VERSION")

    # Set environment variables
    os.environ.update({
        # Predefined values
        "TRAVIS":
        "true",
        "CONTINUOUS_INTEGRATION":
        "true",
        "HAS_JOSH_K_SEAL_OF_APPROVAL":
        "true",
        "RAILS_ENV":
        "test",
        "RACK_ENV":
        "test",
        "MERB_ENV":
        "test",
        "TRAVIS_ALLOW_FAILURE":
        "false",
        "TRAVIS_JOB_NUMBER":
        "1",
        "TRAVIS_TEST_RESULT":
        "0",
        "TRAVIS_COMMIT_RANGE":
        "unknown",
        # Dinamic values
        "TRAVIS_BRANCH":
        target_branch,
        "TRAVIS_COMMIT_MESSAGE":
        commit_message,
        "TRAVIS_OS_NAME":
        sys.platform,
        "TRAVIS_SUDO":
        "true" if getuser() == "root" else "false",
    })

    # Set variables whose values are already directly set in other variables
    equivalent_vars = [
        ("TRAVIS_BUILD_DIR", "CI_PROJECT_DIR"),
        ("TRAVIS_BUILD_ID", "CI_BUILD_ID"),
        ("TRAVIS_BUILD_NUMBER", "CI_JOB_ID"),
        ("TRAVIS_COMMIT", "CI_COMMIT_SHA"),
        ("TRAVIS_EVENT_TYPE", "CI_PIPELINE_SOURCE"),
        ("TRAVIS_JOB_ID", "CI_JOB_ID"),
        ("TRAVIS_REPO_SLUG", "CI_PROJECT_PATH"),
        ("TRAVIS_BUILD_STAGE_NAME", "CI_BUILD_STAGE"),
    ]
    os.environ.update({
        travis_var: os.environ.get(gitlab_var)
        for travis_var, gitlab_var in equivalent_vars
        if gitlab_var in os.environ
    })

    # If within an MR
    is_mr = target_branch != head_branch
    if is_mr:
        os.environ.update({
            # there's no way to know the MR number. For more info, see:
            # https://gitlab.com/gitlab-org/gitlab-ce/issues/15280
            "TRAVIS_PULL_REQUEST":
            "unknown",
            "TRAVIS_PULL_REQUEST_BRANCH":
            head_branch,
            "TRAVIS_PULL_REQUEST_SHA":
            os.environ.get("CI_COMMIT_SHA"),
            "TRAVIS_PULL_REQUEST_SLUG":
            os.environ.get("CI_PROJECT_PATH"),
        })
    else:
        os.environ.update({
            "TRAVIS_PULL_REQUEST": "false",
            "TRAVIS_PULL_REQUEST_BRANCH": "",
            "TRAVIS_PULL_REQUEST_SHA": "",
            "TRAVIS_PULL_REQUEST_SLUG": "",
        })
    return True