Add diff mode support to git module (#3364)
* Add diffmode support to git module This patch adds missing diffmode support to the git module. * Remodel get_diff() and calls to it As proposed by @abadger * Ensure we fetch the required object before performing a diff Also we handle the return code ourselves, so don't leave this up to run_command().
This commit is contained in:
parent
fb255b3607
commit
4ee9cc4b3f
1 changed files with 58 additions and 20 deletions
|
@ -375,6 +375,25 @@ def reset(git_path, module, dest):
|
||||||
cmd = "%s reset --hard HEAD" % (git_path,)
|
cmd = "%s reset --hard HEAD" % (git_path,)
|
||||||
return module.run_command(cmd, check_rc=True, cwd=dest)
|
return module.run_command(cmd, check_rc=True, cwd=dest)
|
||||||
|
|
||||||
|
def get_diff(module, git_path, dest, repo, remote, depth, bare, before, after):
|
||||||
|
''' Return the difference between 2 versions '''
|
||||||
|
if before == None:
|
||||||
|
return { 'prepared': '>> Newly checked out %s' % after }
|
||||||
|
elif before != after:
|
||||||
|
# Ensure we have the object we are referring to during git diff !
|
||||||
|
fetch(git_path, module, repo, dest, after, remote, depth, bare, '')
|
||||||
|
cmd = '%s diff %s %s' % (git_path, before, after)
|
||||||
|
(rc, out, err) = module.run_command(cmd, cwd=dest)
|
||||||
|
if rc == 0 and out:
|
||||||
|
return { 'prepared': out }
|
||||||
|
elif rc == 0:
|
||||||
|
return { 'prepared': '>> No visual differences between %s and %s' % (before, after) }
|
||||||
|
elif err:
|
||||||
|
return { 'prepared': '>> Failed to get proper diff between %s and %s:\n>> %s' % (before, after, err) }
|
||||||
|
else:
|
||||||
|
return { 'prepared': '>> Failed to get proper diff between %s and %s' % (before, after) }
|
||||||
|
return {}
|
||||||
|
|
||||||
def get_remote_head(git_path, module, dest, version, remote, bare):
|
def get_remote_head(git_path, module, dest, version, remote, bare):
|
||||||
cloning = False
|
cloning = False
|
||||||
cwd = None
|
cwd = None
|
||||||
|
@ -761,8 +780,7 @@ def main():
|
||||||
key_file = module.params['key_file']
|
key_file = module.params['key_file']
|
||||||
ssh_opts = module.params['ssh_opts']
|
ssh_opts = module.params['ssh_opts']
|
||||||
|
|
||||||
return_values = {}
|
result = dict( warnings=list() )
|
||||||
return_values['warnings'] = []
|
|
||||||
|
|
||||||
# We screenscrape a huge amount of git commands so use C locale anytime we
|
# We screenscrape a huge amount of git commands so use C locale anytime we
|
||||||
# call run_command()
|
# call run_command()
|
||||||
|
@ -796,13 +814,13 @@ def main():
|
||||||
git_version_used = git_version(git_path, module)
|
git_version_used = git_version(git_path, module)
|
||||||
|
|
||||||
if depth is not None and git_version_used < LooseVersion('1.9.1'):
|
if depth is not None and git_version_used < LooseVersion('1.9.1'):
|
||||||
return_values['warnings'].append("Your git version is too old to fully support the depth argument. Falling back to full checkouts.")
|
result['warnings'].append("Your git version is too old to fully support the depth argument. Falling back to full checkouts.")
|
||||||
depth = None
|
depth = None
|
||||||
|
|
||||||
recursive = module.params['recursive']
|
recursive = module.params['recursive']
|
||||||
track_submodules = module.params['track_submodules']
|
track_submodules = module.params['track_submodules']
|
||||||
|
|
||||||
before = None
|
result.update(before=None)
|
||||||
local_mods = False
|
local_mods = False
|
||||||
repo_updated = None
|
repo_updated = None
|
||||||
if (dest and not os.path.exists(gitconfig)) or (not dest and not allow_clone):
|
if (dest and not os.path.exists(gitconfig)) or (not dest and not allow_clone):
|
||||||
|
@ -812,7 +830,12 @@ def main():
|
||||||
# In those cases we do an ls-remote
|
# In those cases we do an ls-remote
|
||||||
if module.check_mode or not allow_clone:
|
if module.check_mode or not allow_clone:
|
||||||
remote_head = get_remote_head(git_path, module, dest, version, repo, bare)
|
remote_head = get_remote_head(git_path, module, dest, version, repo, bare)
|
||||||
module.exit_json(changed=True, before=before, after=remote_head, **return_values)
|
result.update(changed=True, after=remote_head)
|
||||||
|
if module._diff:
|
||||||
|
diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after'])
|
||||||
|
if diff:
|
||||||
|
result['diff'] = diff
|
||||||
|
module.exit_json(**result)
|
||||||
# there's no git config, so clone
|
# there's no git config, so clone
|
||||||
clone(git_path, module, repo, dest, remote, depth, version, bare, reference, refspec, verify_commit)
|
clone(git_path, module, repo, dest, remote, depth, version, bare, reference, refspec, verify_commit)
|
||||||
repo_updated = True
|
repo_updated = True
|
||||||
|
@ -820,16 +843,17 @@ def main():
|
||||||
# Just return having found a repo already in the dest path
|
# Just return having found a repo already in the dest path
|
||||||
# this does no checking that the repo is the actual repo
|
# this does no checking that the repo is the actual repo
|
||||||
# requested.
|
# requested.
|
||||||
before = get_version(module, git_path, dest)
|
result['before'] = get_version(module, git_path, dest)
|
||||||
module.exit_json(changed=False, before=before, after=before, **return_values)
|
result.update(changed=False, after=result['before'])
|
||||||
|
module.exit_json(**result)
|
||||||
else:
|
else:
|
||||||
# else do a pull
|
# else do a pull
|
||||||
local_mods = has_local_mods(module, git_path, dest, bare)
|
local_mods = has_local_mods(module, git_path, dest, bare)
|
||||||
before = get_version(module, git_path, dest)
|
result['before'] = get_version(module, git_path, dest)
|
||||||
if local_mods:
|
if local_mods:
|
||||||
# failure should happen regardless of check mode
|
# failure should happen regardless of check mode
|
||||||
if not force:
|
if not force:
|
||||||
module.fail_json(msg="Local modifications exist in repository (force=no).", **return_values)
|
module.fail_json(msg="Local modifications exist in repository (force=no).", **result)
|
||||||
# if force and in non-check mode, do a reset
|
# if force and in non-check mode, do a reset
|
||||||
if not module.check_mode:
|
if not module.check_mode:
|
||||||
reset(git_path, module, dest)
|
reset(git_path, module, dest)
|
||||||
|
@ -837,10 +861,14 @@ def main():
|
||||||
# exit if already at desired sha version
|
# exit if already at desired sha version
|
||||||
set_remote_url(git_path, module, repo, dest, remote)
|
set_remote_url(git_path, module, repo, dest, remote)
|
||||||
remote_head = get_remote_head(git_path, module, dest, version, remote, bare)
|
remote_head = get_remote_head(git_path, module, dest, version, remote, bare)
|
||||||
if before == remote_head:
|
if result['before'] == remote_head:
|
||||||
if local_mods:
|
if local_mods:
|
||||||
module.exit_json(changed=True, before=before, after=remote_head,
|
result.update(changed=True, after=remote_head, msg='Local modifications exist')
|
||||||
msg="Local modifications exist", **return_values)
|
if module._diff:
|
||||||
|
diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after'])
|
||||||
|
if diff:
|
||||||
|
result['diff'] = diff
|
||||||
|
module.exit_json(**result)
|
||||||
elif version == 'HEAD':
|
elif version == 'HEAD':
|
||||||
# If the remote and local match and we're using the default of
|
# If the remote and local match and we're using the default of
|
||||||
# HEAD (It's not a real tag) then exit early
|
# HEAD (It's not a real tag) then exit early
|
||||||
|
@ -856,7 +884,12 @@ def main():
|
||||||
|
|
||||||
if repo_updated is None:
|
if repo_updated is None:
|
||||||
if module.check_mode:
|
if module.check_mode:
|
||||||
module.exit_json(changed=True, before=before, after=remote_head, **return_values)
|
result.update(changed=(result['before']!=remote_head), after=remote_head)
|
||||||
|
if module._diff:
|
||||||
|
diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after'])
|
||||||
|
if diff:
|
||||||
|
result['diff'] = diff
|
||||||
|
module.exit_json(**result)
|
||||||
fetch(git_path, module, repo, dest, version, remote, depth, bare, refspec)
|
fetch(git_path, module, repo, dest, version, remote, depth, bare, refspec)
|
||||||
repo_updated = True
|
repo_updated = True
|
||||||
|
|
||||||
|
@ -872,20 +905,25 @@ def main():
|
||||||
|
|
||||||
if module.check_mode:
|
if module.check_mode:
|
||||||
if submodules_updated:
|
if submodules_updated:
|
||||||
module.exit_json(changed=True, before=before, after=remote_head, submodules_changed=True, **return_values)
|
result.update(changed=True, after=remote_head, submodules_changed=True)
|
||||||
else:
|
else:
|
||||||
module.exit_json(changed=False, before=before, after=remote_head, **return_values)
|
result.update(changed=False, after=remote_head)
|
||||||
|
module.exit_json(**result)
|
||||||
|
|
||||||
if submodules_updated:
|
if submodules_updated:
|
||||||
# Switch to version specified
|
# Switch to version specified
|
||||||
submodule_update(git_path, module, dest, track_submodules)
|
submodule_update(git_path, module, dest, track_submodules)
|
||||||
|
|
||||||
# determine if we changed anything
|
# determine if we changed anything
|
||||||
after = get_version(module, git_path, dest)
|
result['after'] = get_version(module, git_path, dest)
|
||||||
|
|
||||||
changed = False
|
result.update(changed=False)
|
||||||
if before != after or local_mods or submodules_updated:
|
if result['before'] != result['after'] or local_mods or submodules_updated:
|
||||||
changed = True
|
result.update(changed=True)
|
||||||
|
if module._diff:
|
||||||
|
diff = get_diff(module, git_path, dest, repo, remote, depth, bare, result['before'], result['after'])
|
||||||
|
if diff:
|
||||||
|
result['diff'] = diff
|
||||||
|
|
||||||
# cleanup the wrapper script
|
# cleanup the wrapper script
|
||||||
if ssh_wrapper:
|
if ssh_wrapper:
|
||||||
|
@ -895,7 +933,7 @@ def main():
|
||||||
# No need to fail if the file already doesn't exist
|
# No need to fail if the file already doesn't exist
|
||||||
pass
|
pass
|
||||||
|
|
||||||
module.exit_json(changed=changed, before=before, after=after, **return_values)
|
module.exit_json(**result)
|
||||||
|
|
||||||
# import module snippets
|
# import module snippets
|
||||||
from ansible.module_utils.basic import *
|
from ansible.module_utils.basic import *
|
||||||
|
|
Loading…
Reference in a new issue