add executable option to hg, refactor in doing so

reviewable/pr18780/r1
Skylar Saveland 11 years ago
parent 3f74c2d986
commit bb4619e716

@ -22,10 +22,7 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>. # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
import os
import shutil
import ConfigParser import ConfigParser
from subprocess import Popen, PIPE
DOCUMENTATION = ''' DOCUMENTATION = '''
--- ---
@ -68,6 +65,13 @@ options:
required: false required: false
default: "no" default: "no"
choices: [ "yes", "no" ] choices: [ "yes", "no" ]
executable:
required: false
default: null
version_added: "1.4"
description:
- Path to hg executable to use. If not supplied,
the normal mechanism for resolving binary paths will be used.
notes: notes:
- If the task seems to be hanging, first verify remote host is in C(known_hosts). - If the task seems to be hanging, first verify remote host is in C(known_hosts).
SSH will prompt user to authorize the first contact with a remote host. One solution is to add SSH will prompt user to authorize the first contact with a remote host. One solution is to add
@ -98,6 +102,7 @@ def _set_hgrc(hgrc, vals):
parser.write(f) parser.write(f)
f.close() f.close()
def _undo_hgrc(hgrc, vals): def _undo_hgrc(hgrc, vals):
parser = ConfigParser.SafeConfigParser() parser = ConfigParser.SafeConfigParser()
parser.read(hgrc) parser.read(hgrc)
@ -111,94 +116,105 @@ def _undo_hgrc(hgrc, vals):
parser.write(f) parser.write(f)
f.close() f.close()
def _hg_command(module, args_list):
(rc, out, err) = module.run_command(['hg'] + args_list)
return (rc, out, err)
def _hg_list_untracked(module, dest):
return _hg_command(module, ['purge', '-R', dest, '--print'])
def get_revision(module, dest):
"""
hg id -b -i -t returns a string in the format:
"<changeset>[+] <branch_name> <tag>"
This format lists the state of the current working copy,
and indicates whether there are uncommitted changes by the
plus sign. Otherwise, the sign is omitted.
Read the full description via hg id --help
"""
(rc, out, err) = _hg_command(module, ['id', '-b', '-i', '-t', '-R', dest])
if rc != 0:
module.fail_json(msg=err)
else:
return out.strip('\n')
def has_local_mods(module, dest): class Hg(object):
now = get_revision(module, dest)
if '+' in now:
return True
else:
return False
def hg_discard(module, dest): def __init__(self, module, dest, repo, revision, hg_path):
before = has_local_mods(module, dest) self.module = module
if not before: self.dest = dest
return False self.repo = repo
self.revision = revision
self.hg_path = self.hg_path
(rc, out, err) = _hg_command(module, ['update', '-C', '-R', dest]) def _command(self, args_list):
if rc != 0: (rc, out, err) = self.module.run_command([self.hg_path] + args_list)
module.fail_json(msg=err) return (rc, out, err)
after = has_local_mods(module, dest) def _list_untracked(self):
if before != after and not after: # no more local modification return self._command(['purge', '-R', self.dest, '--print'])
return True
def hg_purge(module, dest): def get_revision(self):
hgrc = os.path.join(dest, '.hg/hgrc') """
purge_option = [('extensions', 'purge', '')] hg id -b -i -t returns a string in the format:
_set_hgrc(hgrc, purge_option) # enable purge extension "<changeset>[+] <branch_name> <tag>"
This format lists the state of the current working copy,
# before purge, find out if there are any untracked files and indicates whether there are uncommitted changes by the
(rc1, out1, err1) = _hg_list_untracked(module, dest) plus sign. Otherwise, the sign is omitted.
if rc1 != 0:
module.fail_json(msg=err) Read the full description via hg id --help
"""
# there are some untrackd files (rc, out, err) = self._command(['id', '-b', '-i', '-t', '-R', self.dest])
if out1 != '': if rc != 0:
(rc2, out2, err2) = _hg_command(module, ['purge', '-R', dest]) self.module.fail_json(msg=err)
if rc2 == 0:
_undo_hgrc(hgrc, purge_option)
else: else:
module.fail_json(msg=err) return out.strip('\n')
return True
else: def has_local_mods(self):
return False now = self.get_revision()
if '+' in now:
def hg_cleanup(module, dest, force, purge): return True
discarded = False else:
purged = False return False
if force: def discard(self):
discarded = hg_discard(module, dest) before = self.has_local_mods()
if purge: if not before:
purged = hg_purge(module, dest) return False
if discarded or purged:
return True
else:
return False
def hg_pull(module, dest, revision, repo): (rc, out, err) = self._command(['update', '-C', '-R', self.dest])
return _hg_command(module, ['pull', '-r', revision, '-R', dest, repo]) if rc != 0:
self.module.fail_json(msg=err)
after = self.has_local_mods()
if before != after and not after: # no more local modification
return True
def purge(self):
hgrc = os.path.join(self.dest, '.hg/hgrc')
purge_option = [('extensions', 'purge', '')]
_set_hgrc(hgrc, purge_option) # enable purge extension
# before purge, find out if there are any untracked files
(rc1, out1, err1) = self._list_untracked()
if rc1 != 0:
self.module.fail_json(msg=err1)
# there are some untrackd files
if out1 != '':
(rc2, out2, err2) = self._command(['purge', '-R', self.dest])
if rc2 == 0:
_undo_hgrc(hgrc, purge_option)
else:
self.module.fail_json(msg=err2)
return True
else:
return False
def cleanup(self, force, purge):
discarded = False
purged = False
if force:
discarded = self.discard()
if purge:
purged = self.purge()
if discarded or purged:
return True
else:
return False
def hg_update(module, dest, revision): def pull(self):
return _hg_command(module, ['update', '-R', dest]) return self._command(
['pull', '-r', self.revision, '-R', self.dest, self.repo])
def hg_clone(module, repo, dest, revision): def update(self):
return _hg_command(module, ['clone', repo, dest, '-r', revision]) return self._command(['update', '-R', self.dest])
def switch_version(module, dest, revision): def clone(self):
return _hg_command(module, ['update', '-r', revision, '-R', dest]) return self._command(['clone', self.repo, self.dest, '-r', self.revision])
def switch_version(self):
return self._command(['update', '-r', self.revision, '-R', self.dest])
# =========================================== # ===========================================
@ -209,7 +225,8 @@ def main():
dest = dict(required=True), dest = dict(required=True),
revision = dict(default="default", aliases=['version']), revision = dict(default="default", aliases=['version']),
force = dict(default='yes', type='bool'), force = dict(default='yes', type='bool'),
purge = dict(default='no', type='bool') purge = dict(default='no', type='bool'),
executable = dict(default=None),
), ),
) )
repo = module.params['repo'] repo = module.params['repo']
@ -217,6 +234,7 @@ def main():
revision = module.params['revision'] revision = module.params['revision']
force = module.params['force'] force = module.params['force']
purge = module.params['purge'] purge = module.params['purge']
hg_path = module.parames['executable'] or module.get_bin_path('hg', True)
hgrc = os.path.join(dest, '.hg/hgrc') hgrc = os.path.join(dest, '.hg/hgrc')
# initial states # initial states
@ -224,29 +242,31 @@ def main():
changed = False changed = False
cleaned = False cleaned = False
hg = Hg(module, dest, repo, revision, hg_path)
# If there is no hgrc file, then assume repo is absent # If there is no hgrc file, then assume repo is absent
# and perform clone. Otherwise, perform pull and update. # and perform clone. Otherwise, perform pull and update.
if not os.path.exists(hgrc): if not os.path.exists(hgrc):
(rc, out, err) = hg_clone(module, repo, dest, revision) (rc, out, err) = hg.clone()
if rc != 0: if rc != 0:
module.fail_json(msg=err) module.fail_json(msg=err)
else: else:
# get the current state before doing pulling # get the current state before doing pulling
before = get_revision(module, dest) before = hg.get_revision()
# can perform force and purge # can perform force and purge
cleaned = hg_cleanup(module, dest, force, purge) cleaned = hg.cleanup(force, purge)
(rc, out, err) = hg_pull(module, dest, revision, repo) (rc, out, err) = hg.pull()
if rc != 0: if rc != 0:
module.fail_json(msg=err) module.fail_json(msg=err)
(rc, out, err) = hg_update(module, dest, revision) (rc, out, err) = hg.update()
if rc != 0: if rc != 0:
module.fail_json(msg=err) module.fail_json(msg=err)
switch_version(module, dest, revision) hg.switch_version()
after = get_revision(module, dest) after = hg.get_revision()
if before != after or cleaned: if before != after or cleaned:
changed = True changed = True
module.exit_json(before=before, after=after, changed=changed, cleaned=cleaned) module.exit_json(before=before, after=after, changed=changed, cleaned=cleaned)

Loading…
Cancel
Save