# Buggy code
def scm_archive_role(src, scm="git", name=None, version="HEAD", keep_scm_meta=False):
    def run_scm_cmd(cmd, tempdir):
        try:
            stdout = ""
            stderr = ""
            popen = Popen(cmd, cwd=tempdir, stdout=PIPE, stderr=PIPE)
            stdout, stderr = popen.communicate()
        except Exception as e:
            ran = " ".join(cmd)
            display.debug("ran %s:" % ran)
            display.debug("\tstdout: " + stdout)
            display.debug("\tstderr: " + stderr)
            raise AnsibleError("when executing %s: %s" % (ran, to_native(e)))
        if popen.returncode != 0:
            raise AnsibleError(
                "- command %s failed in directory %s (rc=%s)"
                % (" ".join(cmd), tempdir, popen.returncode)
            )

    if scm not in ["hg", "git"]:
        raise AnsibleError("- scm %s is not currently supported" % scm)

    try:
        scm_path = get_bin_path(scm, required=True)
    except (ValueError, OSError, IOError):
        raise AnsibleError(
            "could not find/use %s, it is required to continue with installing %s"
            % (scm, src)
        )

    tempdir = tempfile.mkdtemp(dir=C.DEFAULT_LOCAL_TMP)
    clone_cmd = [scm_path, "clone", src, name]
    run_scm_cmd(clone_cmd, tempdir)

    if scm == "git" and version:
        checkout_cmd = [scm_path, "checkout", version]
        run_scm_cmd(checkout_cmd, os.path.join(tempdir, name))

    temp_file = tempfile.NamedTemporaryFile(
        delete=False, suffix=".tar", dir=C.DEFAULT_LOCAL_TMP
    )
    archive_cmd = None
    if keep_scm_meta:
        display.vvv("tarring %s from %s to %s" % (name, tempdir, temp_file.name))
        with tarfile.open(temp_file.name, "w") as tar:
            tar.add(os.path.join(tempdir, name), arcname=name)
    elif scm == "hg":
        archive_cmd = [scm_path, "archive", "--prefix", "%s/" % name]
        if version:
            archive_cmd.extend(["-r", version])
        archive_cmd.append(temp_file.name)
    elif scm == "git":
        archive_cmd = [
            scm_path,
            "archive",
            "--prefix=%s/" % name,
            "--output=%s" % temp_file.name,
        ]
        if version:
            archive_cmd.append(version)
        else:
            archive_cmd.append("HEAD")

    if archive_cmd is not None:
        display.vvv("archiving %s" % archive_cmd)
        run_scm_cmd(archive_cmd, os.path.join(tempdir, name))

    return temp_file.name


# Traceback (TypeError)
[jenkins@vm61 dummy]$ ansible-galaxy --version
ansible-galaxy 2.7.6
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/srv/var/jenkins/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /srv/var/jenkins/.local/lib/python2.7/site-packages/ansible
executable location = /bin/ansible-galaxy
python version = 2.7.5 (default, Jul 13 2018, 13:06:57) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
[jenkins@vm61 dummy]$ cat roles.yml
# Standards: 0.1
---
- src: ssh://git.rfiserve.net:29418/operations/ansible
scm: git
version: 0.1

[jenkins@vm61 dummy]$ ansible-galaxy install -r roles.yml
ERROR! Unexpected Exception, this is probably a bug: sequence item 2: expected string, float found
to see the full traceback, use -vvv
[jenkins@vm61 dummy]$ ansible-galaxy install -r roles.yml  -vvv
ansible-galaxy 2.7.6
config file = /etc/ansible/ansible.cfg
configured module search path = [u'/srv/var/jenkins/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
ansible python module location = /srv/var/jenkins/.local/lib/python2.7/site-packages/ansible
executable location = /bin/ansible-galaxy
python version = 2.7.5 (default, Jul 13 2018, 13:06:57) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
Using /etc/ansible/ansible.cfg as config file
Opened /srv/var/jenkins/.ansible_galaxy
found role {'scm': 'git', 'src': 'ssh://git.myserver.net:29418/operations/ansible', 'version': 0.1, 'name': 'ansible'} in yaml file
Processing role ansible
ERROR! Unexpected Exception, this is probably a bug: sequence item 2: expected string, float found
the full traceback was:

Traceback (most recent call last):
File "/bin/ansible-galaxy", line 118, in <module>
exit_code = cli.run()
File "/srv/var/jenkins/.local/lib/python2.7/site-packages/ansible/cli/galaxy.py", line 162, in run
self.execute()
File "/srv/var/jenkins/.local/lib/python2.7/site-packages/ansible/cli/__init__.py", line 155, in execute
fn()
File "/srv/var/jenkins/.local/lib/python2.7/site-packages/ansible/cli/galaxy.py", line 398, in execute_install
installed = role.install()
File "/srv/var/jenkins/.local/lib/python2.7/site-packages/ansible/galaxy/role.py", line 201, in install
tmp_file = RoleRequirement.scm_archive_role(keep_scm_meta=self.options.keep_scm_meta, **self.spec)
File "/srv/var/jenkins/.local/lib/python2.7/site-packages/ansible/playbook/role/requirement.py", line 172, in scm_archive_role
run_scm_cmd(checkout_cmd, os.path.join(tempdir, name))
File "/srv/var/jenkins/.local/lib/python2.7/site-packages/ansible/playbook/role/requirement.py", line 150, in run_scm_cmd
ran = " ".join(cmd)
TypeError: sequence item 2: expected string, float found
[jenkins@vm61 dummy]$

# Fixed code
def scm_archive_role(src, scm="git", name=None, version="HEAD", keep_scm_meta=False):
    def run_scm_cmd(cmd, tempdir):
        try:
            stdout = ""
            stderr = ""
            popen = Popen(cmd, cwd=tempdir, stdout=PIPE, stderr=PIPE)
            stdout, stderr = popen.communicate()
        except Exception as e:
            ran = " ".join(cmd)
            display.debug("ran %s:" % ran)
            display.debug("\tstdout: " + stdout)
            display.debug("\tstderr: " + stderr)
            raise AnsibleError("when executing %s: %s" % (ran, to_native(e)))
        if popen.returncode != 0:
            raise AnsibleError(
                "- command %s failed in directory %s (rc=%s)"
                % (" ".join(cmd), tempdir, popen.returncode)
            )

    if scm not in ["hg", "git"]:
        raise AnsibleError("- scm %s is not currently supported" % scm)

    try:
        scm_path = get_bin_path(scm, required=True)
    except (ValueError, OSError, IOError):
        raise AnsibleError(
            "could not find/use %s, it is required to continue with installing %s"
            % (scm, src)
        )

    tempdir = tempfile.mkdtemp(dir=C.DEFAULT_LOCAL_TMP)
    clone_cmd = [scm_path, "clone", src, name]
    run_scm_cmd(clone_cmd, tempdir)

    if scm == "git" and version:
        checkout_cmd = [scm_path, "checkout", to_text(version)]
        run_scm_cmd(checkout_cmd, os.path.join(tempdir, name))

    temp_file = tempfile.NamedTemporaryFile(
        delete=False, suffix=".tar", dir=C.DEFAULT_LOCAL_TMP
    )
    archive_cmd = None
    if keep_scm_meta:
        display.vvv("tarring %s from %s to %s" % (name, tempdir, temp_file.name))
        with tarfile.open(temp_file.name, "w") as tar:
            tar.add(os.path.join(tempdir, name), arcname=name)
    elif scm == "hg":
        archive_cmd = [scm_path, "archive", "--prefix", "%s/" % name]
        if version:
            archive_cmd.extend(["-r", version])
        archive_cmd.append(temp_file.name)
    elif scm == "git":
        archive_cmd = [
            scm_path,
            "archive",
            "--prefix=%s/" % name,
            "--output=%s" % temp_file.name,
        ]
        if version:
            archive_cmd.append(version)
        else:
            archive_cmd.append("HEAD")

    if archive_cmd is not None:
        display.vvv("archiving %s" % archive_cmd)
        run_scm_cmd(archive_cmd, os.path.join(tempdir, name))

    return temp_file.name