import os import shlex from ansible.errors import AnsibleActionFail from ansible.module_utils.common.text.converters import to_text def is_work_tree(action, repo_dir, task_vars): cmd_result = action._execute_module( module_name='ansible.builtin.command', module_args=dict( argv=['git', 'rev-parse', '--is-inside-work-tree'], chdir=repo_dir, ), task_vars=task_vars, ) return not cmd_result.get('failed') def get_status(action, repo_dir, task_vars): cmd_result = action._execute_module( module_name='ansible.builtin.command', module_args=dict( argv=['git', 'status', '--porcelain'], chdir=repo_dir, ), task_vars=task_vars, ) if cmd_result.get('failed'): raise AnsibleActionFail(f"Couldn't get git status for {repo_dir}", result=cmd_result) return to_text(cmd_result['stdout']) def get_dirty_file_list(action, repo_dir, task_vars): status = get_status(action, repo_dir, task_vars) status = status.splitlines() status = [line[3:] for line in status] return status def get_remote_url(action, repo_dir, task_vars, remote='origin'): cmd_result = action._execute_module( module_name='ansible.builtin.command', module_args=dict( argv=['git', 'config', '--local', f'remote.{remote}.url'], chdir=repo_dir, ), task_vars=task_vars, ) if cmd_result.get('failed'): raise AnsibleActionFail(f"Couldn't read the URL of remote '{remote}' in {repo_dir}", result=cmd_result) return cmd_result['stdout'] def update_remote(action, repo_dir, remote, task_vars, accept_hostkey=False): ssh = os.environ.get('GIT_SSH', 'ssh') ssh_opts = '' if accept_hostkey: ssh_opts += ' -o StrictHostKeyChecking=no' ssh_command = shlex.quote(ssh) + ssh_opts cmd_result = action._execute_module( module_name='ansible.builtin.command', module_args=dict( argv=['env', f'GIT_SSH_COMMAND={ssh_command}', 'git', 'remote', 'update', remote], chdir=repo_dir, ), task_vars=task_vars, ) if cmd_result.get('failed'): raise AnsibleActionFail(f"Couldn't update remote '{remote}' for {repo_dir}", result=cmd_result) def is_ancestor(action, repo_dir, remote, version, task_vars): looks_like_hash = all(((c >= '0' and c <= '9') or (c >= 'a' and c <= 'f') for c in version)) remote_versions = [f'{remote}/{version}'] if looks_like_hash: remote_versions += [version] for _version in remote_versions: cmd_result = action._execute_module( module_name='ansible.builtin.command', module_args=dict( argv=['git', 'merge-base', '--is-ancestor', 'HEAD', _version], chdir=repo_dir, ), task_vars=task_vars, ) if cmd_result.get('failed'): if cmd_result.get('stderr'): continue else: return True raise AnsibleActionFail(f"Couldn't deduce how the HEAD of {repo_dir} relates to remote version {remote}/{version}")