diff --git a/source_control/bzr b/source_control/bzr index b1eba0e2e56..52435f66dab 100644 --- a/source_control/bzr +++ b/source_control/bzr @@ -50,6 +50,13 @@ options: description: - If C(yes), any modified files in the working tree will be discarded. + executable: + required: false + default: null + version_added: "1.4" + description: + - Path to bzr executable to use. If not supplied, + the normal mechanism for resolving binary paths will be used. ''' EXAMPLES = ''' @@ -58,67 +65,79 @@ EXAMPLES = ''' ''' import re -import tempfile -def get_version(dest): - ''' samples the version of the bzr branch''' - os.chdir(dest) - cmd = "bzr revno" - revno = os.popen(cmd).read().strip() - return revno -def clone(module, parent, dest, version): - ''' makes a new bzr branch if it does not already exist ''' - dest_dirname = os.path.dirname(dest) - try: - os.makedirs(dest_dirname) - except: - pass - os.chdir(dest_dirname) - if version.lower() != 'head': - cmd = "bzr branch -r %s %s %s" % (version, parent, dest) - else: - cmd = "bzr branch %s %s" % (parent, dest) - return module.run_command(cmd, check_rc=True) +class Bzr(object): + def __init__(self, module, parent, dest, version, bzr_path): + self.module = module + self.parent = parent + self.dest = dest + self.version = version + self.bzr_path = bzr_path -def has_local_mods(dest): - os.chdir(dest) - cmd = "bzr status -S" - lines = os.popen(cmd).read().splitlines() - lines = filter(lambda c: not re.search('^\\?\\?.*$', c), lines) - return len(lines) > 0 + def _command(self, args_list, **kwargs): + (rc, out, err) = self.module.run_command( + [self.bzr_path] + args_list, **kwargs) + return (rc, out, err) -def reset(module,dest,force): - ''' - Resets the index and working tree to head. - Discards any changes to tracked files in the working - tree since that commit. - ''' - os.chdir(dest) - if not force and has_local_mods(dest): - module.fail_json(msg="Local modifications exist in branch (force=no).") - return module.run_command("bzr revert", check_rc=True) + def get_version(self): + '''samples the version of the bzr branch''' + os.chdir(self.dest) + cmd = "%s revno" % self.bzr_path + revno = os.popen(cmd).read().strip() + return revno -def fetch(module, dest, version): - ''' updates branch from remote sources ''' - os.chdir(dest) - if version.lower() != 'head': - (rc, out, err) = module.run_command("bzr pull -r %s" % version) - else: - (rc, out, err) = module.run_command("bzr pull") - if rc != 0: - module.fail_json(msg="Failed to pull") - return (rc, out, err) + def clone(self): + '''makes a new bzr branch if it does not already exist''' + dest_dirname = os.path.dirname(self.dest) + try: + os.makedirs(dest_dirname) + except: + pass + os.chdir(dest_dirname) + if self.version.lower() != 'head': + args_list = ["branch", "-r", self.version, self.parent, self.dest] + else: + args_list = ["branch", self.parent, self.dest] + return self._command(args_list, check_rc=True) -def switch_version(module, dest, version): - ''' once pulled, switch to a particular revno or revid''' - os.chdir(dest) - cmd = '' - if version.lower() != 'head': - cmd = "bzr revert -r %s" % version - else: - cmd = "bzr revert" - return module.run_command(cmd, check_rc=True) + def has_local_mods(self): + os.chdir(self.dest) + cmd = "%s status -S" % self.bzr_path + lines = os.popen(cmd).read().splitlines() + lines = filter(lambda c: not re.search('^\\?\\?.*$', c), lines) + return len(lines) > 0 + + def reset(self, force): + ''' + Resets the index and working tree to head. + Discards any changes to tracked files in the working + tree since that commit. + ''' + os.chdir(self.dest) + if not force and self.has_local_mods(): + self.module.fail_json(msg="Local modifications exist in branch (force=no).") + return self._command(["revert"], check_rc=True) + + def fetch(self): + '''updates branch from remote sources''' + os.chdir(self.dest) + if self.version.lower() != 'head': + (rc, out, err) = self._command(["pull", "-r", self.version]) + else: + (rc, out, err) = self._command(["pull"]) + if rc != 0: + self.module.fail_json(msg="Failed to pull") + return (rc, out, err) + + def switch_version(self): + '''once pulled, switch to a particular revno or revid''' + os.chdir(self.dest) + if self.version.lower() != 'head': + args_list = ["revert", "-r", self.version] + else: + args_list = ["revert"] + return self._command(args_list, check_rc=True) # =========================================== @@ -128,7 +147,8 @@ def main(): dest=dict(required=True), name=dict(required=True, aliases=['parent']), version=dict(default='head'), - force=dict(default='yes', type='bool') + force=dict(default='yes', type='bool'), + executable=dict(default=None), ) ) @@ -136,34 +156,38 @@ def main(): parent = module.params['name'] version = module.params['version'] force = module.params['force'] + bzr_path = module.params['executable'] or module.get_bin_path('bzr', True) bzrconfig = os.path.join(dest, '.bzr', 'branch', 'branch.conf') rc, out, err, status = (0, None, None, None) + bzr = Bzr(module, parent, dest, version, bzr_path) + # if there is no bzr configuration, do a branch operation # else pull and switch the version before = None local_mods = False if not os.path.exists(bzrconfig): - (rc, out, err) = clone(module, parent, dest, version) + (rc, out, err) = bzr.clone() + else: # else do a pull - local_mods = has_local_mods(dest) - before = get_version(dest) - (rc, out, err) = reset(module, dest, force) + local_mods = bzr.has_local_mods() + before = bzr.get_version() + (rc, out, err) = bzr.reset(force) if rc != 0: module.fail_json(msg=err) - (rc, out, err) = fetch(module, dest, version) + (rc, out, err) = bzr.fetch() if rc != 0: module.fail_json(msg=err) # switch to version specified regardless of whether # we cloned or pulled - (rc, out, err) = switch_version(module, dest, version) + (rc, out, err) = bzr.switch_version() # determine if we changed anything - after = get_version(dest) + after = bzr.get_version() changed = False if before != after or local_mods: