Exemple #1
0
def test_echo(capfd):
    query = "foobar"
    cli.echo(query, nl=False)
    assert_stdout(capfd, query)

    cli.echo(query, nl=True)
    assert_stdout(capfd, "{}\n".format(query))
Exemple #2
0
def get_registry_from_requirements(requirements,
                                   sync=False,
                                   jobs=1,
                                   only_packages=[],
                                   resolve=False,
                                   file=None,
                                   ignore_packages=[],
                                   latest=False):
    path = osp.realpath(requirements)

    if not osp.exists(path):
        cli.echo(cli_format("{} not found.".format(path), cli.RED), file=file)
        sys.exit(os.EX_NOINPUT)
    else:
        packages = _pip.parse_requirements(requirements, session="hack")

        if only_packages:
            packages = [p for p in packages if p.name in only_packages]

        if ignore_packages:
            packages = [
                p for p in packages if p["name"] not in ignore_packages
            ]

        registry = Registry(source=path,
                            packages=packages,
                            sync=sync,
                            resolve=resolve,
                            jobs=jobs,
                            latest=latest)

    logger.info("Packages within requirements %s found: %s..." %
                (requirements, registry.packages))

    return registry
Exemple #3
0
def command():
    parser = get_parser()
    args = parser.parse_args()

    packages = _pip.get_installed_distributions()
    npackages = len(packages)

    query = "Do you wish to update {} packages?".format(npackages)

    if args.yes or cli.confirm(query):
        for i, package in enumerate(packages):
            name = package.project_name

            info = cli.format(
                "Updating {} of {} packages: {}".format(
                    i + 1, npackages,
                    name if args.no_color else cli.format(name, cli.GREEN)),
                cli.BOLD)

            cli.echo(info)

            params = list_filter([
                "install", "--quiet" if not args.verbose else None,
                "--no-cache", "--upgrade", name
            ],
                                 filter_=bool)

            _pip.main(params)

        cli.echo(cli.format("UPGRADED ALL THE PACKAGES!", cli.BOLD))

    return 0
Exemple #4
0
def test_echo(capfd):
    query = "foobar"
    cli.echo(query, nl=False)
    out, err = capfd.readouterr()

    assert out == query

    cli.echo(query, nl=True)
    out, err = capfd.readouterr()
    assert out == "{}\n".format(query)
Exemple #5
0
def update_pip(pip_exec, user=None, quiet=None, file=None):
    cli.echo(cli_format("Updating %s..." % pip_exec, cli.YELLOW), file=file)

    output = pip_upgrade("pip", pip_exec=pip_exec, user=user, quiet=quiet)

    if isinstance(output, int):
        code = output
    else:
        code = output[0]

    if not code:
        cli.echo("%s upto date." % cli_format(pip_exec, cli.CYAN), file=file)

    return output
Exemple #6
0
def get_registry_from_requirements(requirements, sync=False):
    path = osp.realpath(requirements)

    if not osp.exists(path):
        cli.echo(cli_format("{} not found.".format(path), cli.RED))
        sys.exit(os.EX_NOINPUT)
    else:
        packages = _pip.parse_requirements(requirements, session="hack")
        registry = Registry(source=path, packages=packages, sync=sync)

    logger.info("Packages within requirements %s found: %s..." %
                (requirements, registry.packages))

    return registry
Exemple #7
0
def update_pip(pip_exec, user = None, quiet = None):
	cli.echo(cli_format("Updating %s..." % pip_exec, cli.YELLOW))

	output = _pip.call("install", "pip", pip_exec = pip_exec, 
		user = user, quiet = quiet, no_cache_dir = True, upgrade = True)

	if isinstance(output, int):
		code = output
	else:
		code = output[0]

	if not code:
		cli.echo("%s upto date." % cli_format(pip_exec, cli.CYAN))

	return output
Exemple #8
0
def test_echo(capfd, tmpdir):
    query = "foobar"
    cli.echo(query, nl=False)
    assert_stdout(capfd, query)

    cli.echo(query, nl=True)
    assert_stdout(capfd, "{}\n".format(query))

    f = tmpdir.join("tmp")
    cli.echo(query, nl=True, file=str(f))
    assert f.read() == "foobar\n"
Exemple #9
0
def command(**ARGUMENTS):
    try:
        return _command(**ARGUMENTS)
    except Exception:
        cli.echo()

        traceback_str = traceback.format_exc()
        cli.echo(traceback_str)

        cli.echo(
            cli_format(
                """\
An error occured while performing the above command. This could be an issue with
"pipupgrade". Kindly post an issue at https://github.com/achillesrasquinha/pipupgrade/issues""",
                cli.RED))
Exemple #10
0
def update_registry(registry,
                    yes=False,
                    user=False,
                    check=False,
                    latest=False,
                    interactive=False,
                    format_="table",
                    all=False,
                    filter_=[],
                    file=None,
                    raise_err=True,
                    verbose=False,
                    upgrade_type=("minor", "patch")):
    source = registry.source
    packages = registry.packages

    if filter_:
        packages = [p for p in packages if p.name in filter_]

    table = Table(
        header=["Name", "Current Version", "Latest Version", "Home Page"])
    nodes = []
    render = False
    dinfo = []  # Information DataFrame

    for package in packages:
        package.source = source
        package.installed = registry.installed

        current_version = package.current_version

        if all or current_version:
            current_version = current_version.replace("==", "")

        if all or (package.latest_version
                   and current_version != package.latest_version):
            render = True

            if format_ in _DEPENDENCY_FORMATS:
                nodes.append(package)
            else:
                table.insert([
                    cli_format(
                        package.name,
                        _SEMVER_COLOR_MAP.get(package.difference, cli.CLEAR)),
                    package.current_version or "na",
                    _cli_format_semver(package.latest_version,
                                       package.difference),
                    cli_format(package.home_page, cli.CYAN)
                ])

            dinfo.append(package)

    stitle = "Installed Distributions (%s)" % source if registry.installed else source

    if render:
        if format_ in _DEPENDENCY_FORMATS:
            nodes = _resolve_dependencies(nodes)
            dinfo = nodes

        if format_ == "tree":
            string = _render_dependency_tree(nodes)
        elif format_ == "json":
            string = _render_json(nodes)
        elif format_ == "yaml":
            string = _render_yaml(nodes)
        elif format_ == "table":
            string = table.render()

        cli.echo("\nSource: %s\n" % stitle, file=file)

        if not interactive or check:
            cli.echo(string, file=file)
            cli.echo(file=file)

        if not check:
            packages = [
                p for p in dinfo
                if p.difference in upgrade_type or p.difference == "major"
            ]
            packages = [
                p for p in dinfo if p.difference != "major"
                or getattr(p, "has_dependency_conflict", False) or latest
            ]

            npackages = len(packages)

            spackages = pluralize("package", npackages)  # Packages "string"
            query = "Do you wish to update %s %s?" % (npackages, spackages)

            if npackages and (yes or interactive
                              or cli.confirm(query, quit_=True)):
                for i, package in enumerate(packages):
                    update = True

                    query = "%s (%s) -> (%s)" % (cli_format(
                        package.name,
                        _SEMVER_COLOR_MAP.get(package.difference, cli.CLEAR)),
                                                 package.current_version,
                                                 _cli_format_semver(
                                                     package.latest_version,
                                                     package.difference))

                    if interactive:
                        update = yes or cli.confirm(query)

                    if update:
                        cli.echo(cli_format(
                            "Updating %s of %s %s: %s" %
                            (i + 1, npackages, spackages,
                             cli_format(package.name, cli.GREEN)), cli.BOLD),
                                 file=file)

                        if not package.installed:
                            _update_requirements(package.source, package)
                        else:
                            try:
                                _pip.call("install",
                                          package.name,
                                          pip_exec=package.source,
                                          user=user,
                                          quiet=not verbose,
                                          no_cache_dir=True,
                                          upgrade=True)
                            except PopenError as e:
                                if raise_err:
                                    raise
    else:
        cli.echo("%s upto date." % cli_format(stitle, cli.CYAN), file=file)
def command(pip_path=[],
            requirements=[],
            pipfile=[],
            project=None,
            pull_request=False,
            git_username=None,
            git_email=None,
            github_access_token=None,
            github_reponame=None,
            github_username=None,
            target_branch="master",
            latest=False,
            format="table",
            all=False,
            pip=False,
            self=False,
            jobs=1,
            user=False,
            check=False,
            interactive=False,
            yes=False,
            no_included_requirements=False,
            no_cache=False,
            no_color=True,
            output=None,
            force=False,
            verbose=False):
    if not verbose:
        logger.setLevel(log.NOTSET)

    logger.info("Environment: %s" % environment())

    cli.echo(cli_format("Checking...", cli.YELLOW))
    logger.info("Arguments Passed: %s" % locals())

    pip_path = pip_path or []
    pip_path = [which(p) for p in pip_path] or _pip._PIP_EXECUTABLES

    logger.info("`pip` executables found: %s" % pip_path)

    logger.info("Using %s jobs..." % jobs)

    registries = []

    if pip:
        logger.info("Updating pip executables: %s" % " ".join(pip_path))

        with parallel.no_daemon_pool(processes=jobs) as pool:
            pool.map(
                partial(update_pip, **{
                    "user": user,
                    "quiet": not verbose
                }), pip_path)

    if self:
        package = __name__
        logger.info("Updating %s..." % package)

        cli.echo(cli_format("Updating %s..." % package, cli.YELLOW))

        _pip.call("install",
                  package,
                  user=user,
                  quiet=not verbose,
                  no_cache=True,
                  upgrade=True)

        cli.echo("%s upto date." % cli_format(package, cli.CYAN))
    else:
        if project:
            project = sequencify(project)
            requirements = requirements or []
            pipfile = pipfile or []

            logger.info("Detecting projects and its dependencies...")

            with parallel.no_daemon_pool(processes=jobs) as pool:
                project = pool.map(
                    partial(Project.from_path, **{"recursive_search": force}),
                    project)

                requirements += flatten(map(lambda p: p.requirements, project))
                pipfile += flatten(
                    map(lambda p: [p.pipfile] if p.pipfile else [], project))

            logger.info("Updating projects %s..." % project)

        if requirements:
            logger.info("Detecting requirements...")

            if not no_included_requirements:
                with parallel.no_daemon_pool(processes=jobs) as pool:
                    results = pool.map(get_included_requirements, requirements)
                    requirements += flatten(results)

            logger.info("Requirements found: %s" % requirements)

            with parallel.no_daemon_pool(processes=jobs) as pool:
                results = pool.map(
                    partial(get_registry_from_requirements, **{
                        "sync": no_cache,
                        "jobs": jobs
                    }), requirements)
                registries += results
        else:
            with parallel.no_daemon_pool(processes=jobs) as pool:
                results = pool.map(
                    partial(
                        get_registry_from_pip, **{
                            "user": user,
                            "sync": no_cache,
                            "outdated": not all,
                            "build_dependency_tree": format
                            in _DEPENDENCY_FORMATS,
                            "jobs": jobs
                        }), pip_path)

                registries += results

        logger.info("Updating registries: %s..." % registries)

        # TODO: Tweaks within parallel.no_daemon_pool to run serially.
        if yes:
            with parallel.no_daemon_pool(processes=jobs) as pool:
                results = pool.map(
                    partial(
                        update_registry, **{
                            "yes": yes,
                            "user": user,
                            "check": check,
                            "latest": latest,
                            "interactive": interactive,
                            "verbose": verbose,
                            "format_": format,
                            "all": all
                        }), registries)
        else:
            for registry in registries:
                update_registry(registry,
                                yes=yes,
                                user=user,
                                check=check,
                                latest=latest,
                                interactive=interactive,
                                verbose=verbose,
                                format_=format,
                                all=all)

        if pipfile:
            logger.info("Updating Pipfiles: %s..." % pipfile)

            cli.echo(
                cli_format("Updating Pipfiles: %s..." % ", ".join(pipfile),
                           cli.YELLOW))

            with parallel.no_daemon_pool(processes=jobs) as pool:
                results = pool.map(
                    partial(update_pipfile, **{"verbose": verbose}), pipfile)

                if builtins.all(results):
                    cli.echo(cli_format("Pipfiles upto date.", cli.GREEN))

        if project and pull_request:
            errstr = '%s not found. Use %s or the environment variable "%s" to set value.'

            if not git_username:
                raise ValueError(errstr % ("Git Username", "--git-username",
                                           getenvvar("GIT_USERNAME")))
            if not git_email:
                raise ValueError(
                    errstr %
                    ("Git Email", "--git-email", getenvvar("GIT_EMAIL")))

            for p in project:
                popen("git config user.name  %s" % git_username, cwd=p.path)
                popen("git config user.email %s" % git_email, cwd=p.path)

                _, output, _ = popen("git status -s", output=True)

                if output:
                    branch = get_timestamp_str(format_="%Y%m%d%H%M%S")
                    popen("git checkout -B %s" % branch, quiet=not verbose)

                    title = "fix(dependencies): Update dependencies to latest"
                    body = ""

                    # TODO: cross-check with "git add" ?
                    files = p.requirements + [p.pipfile]
                    popen("git add %s" % " ".join(files),
                          quiet=not verbose,
                          cwd=p.path)
                    popen("git commit -m '%s'" % title,
                          quiet=not verbose,
                          cwd=p.path)

                    popen("git push origin %s" % branch,
                          quiet=not verbose,
                          cwd=p.path)

                    if not github_reponame:
                        raise ValueError(
                            errstr % ("GitHub Reponame", "--github-reponame",
                                      getenvvar("GITHUB_REPONAME")))
                    if not github_username:
                        raise ValueError(
                            errstr % ("GitHub Username", "--github-username",
                                      getenvvar("GITHUB_USERNAME")))

                    url = "/".join([
                        "https://api.github.com", "repos", github_username,
                        github_reponame, "pulls"
                    ])
                    headers = dict({
                        "Content-Type":
                        "application/json",
                        "Authorization":
                        "token %s" % github_access_token
                    })
                    data = dict(head="%s:%s" % (git_username, branch),
                                base=target_branch,
                                title=title,
                                body=body)

                    # Although there's monkey patch support for the "requests"
                    # library, avoid using the "json" parameter which was
                    # added in requests 2.4.2+
                    response = req.post(url,
                                        data=json.dumps(data),
                                        headers=headers)

                    if response.ok:
                        response = response.json()
                        number = response["number"]

                        url = "/".join(
                            map(str, [
                                "https://github.com", github_username,
                                github_reponame, "pull", number
                            ]))
                        message = "Created a Pull Request at %s" % url

                        cli.echo(cli_format(message, cli.GREEN))
                    else:
                        response.raise_for_status()
Exemple #12
0
def update_registry(registry,
                    yes=False,
                    user=False,
                    check=False,
                    latest=False,
                    interactive=False,
                    verbose=False):
    source = registry.source
    packages = registry.packages

    table = Table(
        header=["Name", "Current Version", "Latest Version", "Home Page"])
    dinfo = []  # Information DataFrame

    for package in packages:
        package.source = source
        package.installed = registry.installed

        if package.latest_version and package.current_version != package.latest_version:
            diff_type = None

            try:
                diff_type = semver.difference(package.current_version,
                                              package.latest_version)
            except (TypeError, ValueError):
                pass

            table.insert([
                cli_format(package.name,
                           _SEMVER_COLOR_MAP.get(diff_type, cli.CLEAR)),
                package.current_version or "na",
                _cli_format_semver(package.latest_version, diff_type),
                cli_format(package.home_page, cli.CYAN)
            ])

            package.diff_type = diff_type

            dinfo.append(package)

        if not registry.installed:
            _update_requirements(package.source, package)

    stitle = "Installed Distributions (%s)" % source if registry.installed else source

    if not table.empty:
        string = table.render()

        cli.echo("\nSource: %s\n" % stitle)

        if not interactive:
            cli.echo(string)
            cli.echo()

        if not check:
            packages = [p for p in dinfo if p.diff_type != "major" or latest]
            npackages = len(packages)

            spackages = pluralize("package", npackages)  # Packages "string"
            query = "Do you wish to update %s %s?" % (npackages, spackages)

            if npackages and (yes or interactive
                              or cli.confirm(query, quit_=True)):
                for i, package in enumerate(packages):
                    update = True

                    query = "%s (%s > %s)" % (cli_format(
                        package.name,
                        _SEMVER_COLOR_MAP.get(package.diff_type, cli.CLEAR)),
                                              package.current_version,
                                              _cli_format_semver(
                                                  package.latest_version,
                                                  package.diff_type))

                    if interactive:
                        update = yes or cli.confirm(query)

                    if update:
                        cli.echo(
                            cli_format(
                                "Updating %s of %s %s: %s" %
                                (i + 1, npackages, spackages,
                                 cli_format(package.name, cli.GREEN)),
                                cli.BOLD))

                        _pip.call("install",
                                  package.name,
                                  pip_exec=package.source,
                                  user=user,
                                  quiet=not verbose,
                                  no_cache_dir=True,
                                  upgrade=True)

                        if not package.installed:
                            _update_requirements(package.source, package)
    else:
        cli.echo("%s upto date." % cli_format(stitle, cli.CYAN))
Exemple #13
0
def _command(*args, **kwargs):
    check_update_available()

    a = to_params(kwargs)

    if not a.verbose:
        logger.setLevel(log.NOTSET)

    logger.info("Environment: %s" % environment())
    logger.info("Arguments Passed: %s" % locals())

    if a.doctor:
        logger.info("Performing Diagnostics and attempting to fix.")

        if a.clean:
            path_config = get_config_path(name=NAME)
            paths = [osp.join(path_config, "db.db")]

            for path in paths:
                remove(path)

        # check database and repair.
    else:
        if a.resolve:
            import_or_raise("mixology")
            import_or_raise("semver", name="poetry-semver")

            populate_db = import_handler("pipupgrade.pubgrub.populate_db")
            populate_db()

        file_ = a.output

        if file_:
            logger.info("Writing to output file %s..." % file_)
            touch(file_)

        cli.echo(cli_format("Checking...", cli.YELLOW), file=file_)

        pip_path = a.pip_path or []
        pip_path = [which(p) for p in pip_path] or _pip._PIP_EXECUTABLES

        logger.info("`pip` executables found: %s" % pip_path)

        logger.info("Using %s jobs..." % a.jobs)

        registries = []

        if a.pip:
            logger.info("Updating pip executables: %s" % " ".join(pip_path))

            with parallel.no_daemon_pool(processes=a.jobs) as pool:
                pool.imap_unordered(
                    partial(
                        update_pip, **{
                            "user": a.user,
                            "quiet": not a.verbose,
                            "file": file_
                        }), pip_path)

        if a.self:
            package = NAME
            logger.info("Updating %s..." % package)

            cli.echo(cli_format("Updating %s..." % package, cli.YELLOW),
                     file=file_)

            _pip.call("install",
                      package,
                      user=a.user,
                      quiet=not a.verbose,
                      no_cache=True,
                      upgrade=True,
                      output=file_)

            cli.echo("%s upto date." % cli_format(package, cli.CYAN),
                     file=file_)
        else:
            requirements = sequencify(a.requirements or [])
            pipfile = sequencify(a.pipfile or [])

            if a.project:
                project = sequencify(a.project)

                logger.info("Detecting projects and its dependencies...")

                with parallel.no_daemon_pool(processes=a.jobs) as pool:
                    project = pool.imap_unordered(
                        partial(Project.from_path, **{"depth_search":
                                                      a.force}), project)

                    requirements += flatten(
                        map(lambda p: p.requirements, project))
                    pipfile += flatten(
                        map(lambda p: [p.pipfile]
                            if p.pipfile else [], project))

                logger.info("Updating projects %s..." % project)

            if requirements:
                logger.info("Detecting requirements...")

                if not a.no_included_requirements:
                    with parallel.no_daemon_pool(processes=a.jobs) as pool:
                        results = pool.imap_unordered(
                            get_included_requirements, requirements)
                        requirements += flatten(results)

                    requirements = list(set(requirements))

                logger.info("Requirements found: %s" % requirements)

                with parallel.no_daemon_pool(processes=a.jobs) as pool:
                    results = pool.imap_unordered(
                        partial(
                            get_registry_from_requirements, **{
                                "sync": a.no_cache,
                                "jobs": a.jobs,
                                "only_packages": a.packages,
                                "file": file_,
                                "ignore_packages": a.ignore,
                                "resolve": a.resolve,
                                "latest": a.latest
                            }), requirements)
                    registries += results
            else:
                with parallel.no_daemon_pool(processes=a.jobs) as pool:
                    for registry in pool.imap_unordered(
                            partial(
                                get_registry_from_pip, **{
                                    "user": a.user,
                                    "sync": a.no_cache,
                                    "outdated": not a.all,
                                    "build_dependency_tree": a.format
                                    in _DEPENDENCY_FORMATS,
                                    "jobs": a.jobs,
                                    "only_packages": a.packages,
                                    "ignore_packages": a.ignore,
                                    "resolve": a.resolve,
                                    "latest": a.latest
                                }), pip_path):
                        registries.append(registry)

            logger.info("Updating registries: %s..." % registries)

            for registry in registries:
                update_registry(registry,
                                yes=a.yes,
                                user=a.user,
                                check=a.check,
                                latest=a.latest,
                                interactive=a.interactive,
                                verbose=a.verbose,
                                format_=a.format,
                                all=a.all,
                                filter_=a.packages,
                                file=file_,
                                raise_err=not a.ignore_error,
                                upgrade_type=a.upgrade_type)

            if pipfile:
                logger.info("Updating Pipfiles: %s..." % pipfile)

                cli.echo(cli_format(
                    "Updating Pipfiles: %s..." % ", ".join(pipfile),
                    cli.YELLOW),
                         file=file_)

                with parallel.no_daemon_pool(processes=a.jobs) as pool:
                    results = pool.imap_unordered(
                        partial(update_pipfile, **{"verbose": a.verbose}),
                        pipfile)

                    if builtins.all(results):
                        cli.echo(cli_format("Pipfiles upto date.", cli.GREEN),
                                 file=file_)

            if a.project and a.pull_request:
                errstr = '%s not found. Use %s or the environment variable "%s" to set value.'

                if not a.git_username:
                    raise ValueError(errstr %
                                     ("Git Username", "--git-username",
                                      getenvvar("GIT_USERNAME")))
                if not a.git_email:
                    raise ValueError(
                        errstr %
                        ("Git Email", "--git-email", getenvvar("GIT_EMAIL")))

                for p in project:
                    popen("git config user.name  %s" % a.git_username,
                          cwd=p.path)
                    popen("git config user.email %s" % a.git_email, cwd=p.path)

                    _, output, _ = popen("git status -s",
                                         output=True,
                                         cwd=p.path)

                    if output:
                        branch = get_timestamp_str(format_="%Y%m%d%H%M%S")
                        popen("git checkout -B %s" % branch,
                              quiet=not a.verbose,
                              cwd=p.path)

                        title = "fix(dependencies): Update dependencies to latest"
                        body = ""

                        # TODO: cross-check with "git add" ?
                        files = p.requirements + [p.pipfile]
                        popen("git add %s" % " ".join(files),
                              quiet=not a.verbose,
                              cwd=p.path)
                        popen("git commit -m '%s'" % title,
                              quiet=not a.verbose,
                              cwd=p.path)

                        popen("git push origin %s" % branch,
                              quiet=not a.verbose,
                              cwd=p.path)

                        if not a.github_reponame:
                            raise ValueError(
                                errstr %
                                ("GitHub Reponame", "--github-reponame",
                                 getenvvar("GITHUB_REPONAME")))
                        if not a.github_username:
                            raise ValueError(
                                errstr %
                                ("GitHub Username", "--github-username",
                                 getenvvar("GITHUB_USERNAME")))

                        url = "/".join([
                            "https://api.github.com", "repos",
                            a.github_username, a.github_reponame, "pulls"
                        ])
                        headers = dict({
                            "Content-Type":
                            "application/json",
                            "Authorization":
                            "token %s" % a.github_access_token
                        })
                        data = dict(head="%s:%s" % (a.git_username, branch),
                                    base=a.target_branch,
                                    title=title,
                                    body=body)

                        # Although there's monkey patch support for the "requests"
                        # library, avoid using the "json" parameter which was
                        # added in requests 2.4.2+
                        response = req.post(url,
                                            data=json.dumps(data),
                                            headers=headers)

                        if response.ok:
                            response = response.json()
                            number = response["number"]

                            url = "/".join(
                                map(str, [
                                    "https://github.com", a.github_username,
                                    a.github_reponame, "pull", number
                                ]))
                            message = "Created a Pull Request at %s" % url

                            cli.echo(cli_format(message, cli.GREEN),
                                     file=file_)
                        else:
                            response.raise_for_status()
Exemple #14
0
def command(pip_path=[],
            requirements=[],
            pipfile=[],
            project=None,
            pull_request=False,
            git_username=None,
            git_email=None,
            github_access_token=None,
            github_reponame=None,
            github_username=None,
            target_branch="master",
            latest=False,
            self=False,
            user=False,
            check=False,
            interactive=False,
            yes=False,
            no_color=True,
            verbose=False):
    cli.echo(cli_format("Checking...", cli.YELLOW))

    pip_path = pip_path or []
    pip_path = [which(p) for p in pip_path] or _pip._PIP_EXECUTABLES

    registries = []

    if self:
        package = __name__

        _pip.call("install",
                  package,
                  user=user,
                  quiet=not verbose,
                  no_cache=True,
                  upgrade=True)
        cli.echo("%s upto date." % cli_format(package, cli.CYAN))
    else:
        if project:
            requirements = requirements or []
            pipfile = pipfile or []

            for i, p in enumerate(project):
                project[i] = Project(osp.abspath(p))
                requirements += project[i].requirements
                pipfile += [project[i].pipfile]

        if requirements:
            for requirement in requirements:
                path = osp.realpath(requirement)

                if not osp.exists(path):
                    cli.echo(cli_format("{} not found.".format(path), cli.RED))
                    sys.exit(os.EX_NOINPUT)
                else:
                    requirements += _get_included_requirements(requirement)

            for requirement in requirements:
                path = osp.realpath(requirement)

                if not osp.exists(path):
                    cli.echo(cli_format("{} not found.".format(path), cli.RED))
                    sys.exit(os.EX_NOINPUT)
                else:
                    packages = _pip.parse_requirements(requirement,
                                                       session="hack")
                    registry = Registry(source=path, packages=packages)

                    registries.append(registry)
        else:
            for pip_ in pip_path:
                _, output, _ = _pip.call("list", outdated = True, \
                 format = "json", pip_exec = pip_)
                packages = json.loads(output)
                registry = Registry(source=pip_,
                                    packages=packages,
                                    installed=True)

                registries.append(registry)
                # _pip.get_installed_distributions() # https://github.com/achillesrasquinha/pipupgrade/issues/13

        for registry in registries:
            source = registry.source
            packages = registry.packages

            table = Table(header=[
                "Name", "Current Version", "Latest Version", "Home Page"
            ])
            dinfo = []  # Information DataFrame

            for package in packages:
                package = Package(package)
                package.source = source
                package.installed = registry.installed

                if package.latest_version and package.current_version != package.latest_version:
                    diff_type = None

                    try:
                        diff_type = semver.difference(package.current_version,
                                                      package.latest_version)
                    except (TypeError, ValueError):
                        pass

                    table.insert([
                        cli_format(package.name,
                                   _SEMVER_COLOR_MAP.get(diff_type,
                                                         cli.CLEAR)),
                        package.current_version or "na",
                        _cli_format_semver(package.latest_version, diff_type),
                        cli_format(package.home_page, cli.CYAN)
                    ])

                    package.diff_type = diff_type

                    dinfo.append(package)

                if not registry.installed:
                    _update_requirements(package.source, package)

            stitle = "Installed Distributions (%s)" % source if registry.installed else source

            if not table.empty:
                string = table.render()

                cli.echo("\nSource: %s\n" % stitle)

                if not interactive:
                    cli.echo(string)
                    cli.echo()

                if not check:
                    packages = [
                        p for p in dinfo if p.diff_type != "major" or latest
                    ]
                    npackages = len(packages)

                    spackages = pluralize("package",
                                          npackages)  # Packages "string"
                    query = "Do you wish to update %s %s?" % (npackages,
                                                              spackages)

                    if npackages and (yes or interactive
                                      or cli.confirm(query, quit_=True)):
                        for i, package in enumerate(packages):
                            update = True

                            query = "%s (%s > %s)" % (
                                cli_format(
                                    package.name,
                                    _SEMVER_COLOR_MAP.get(
                                        package.diff_type,
                                        cli.CLEAR)), package.current_version,
                                _cli_format_semver(package.latest_version,
                                                   package.diff_type))

                            if interactive:
                                update = yes or cli.confirm(query)

                            if update:
                                cli.echo(
                                    cli_format(
                                        "Updating %s of %s %s: %s" %
                                        (i + 1, npackages, spackages,
                                         cli_format(package.name, cli.GREEN)),
                                        cli.BOLD))

                                _pip.call("install",
                                          package.name,
                                          pip_exec=package.source,
                                          user=user,
                                          quiet=not verbose,
                                          no_cache_dir=True,
                                          upgrade=True)

                                if not package.installed:
                                    _update_requirements(
                                        package.source, package)
            else:
                cli.echo("%s upto date." % cli_format(stitle, cli.CYAN))

        if pipfile:
            for pipf in pipfile:
                realpath = osp.realpath(pipf)
                basepath = osp.dirname(realpath)

                pipenv = which("pipenv", raise_err=True)
                popen("%s update" % pipenv, quiet=not verbose, cwd=basepath)

                cli.echo("%s upto date." % cli_format(realpath, cli.CYAN))

        if project and pull_request:
            errstr = '%s not found. Use %s or the environment variable "%s" to set value.'

            if not git_username:
                raise ValueError(errstr % ("Git Username", "--git-username",
                                           getenvvar("GIT_USERNAME")))
            if not git_email:
                raise ValueError(
                    errstr %
                    ("Git Email", "--git-email", getenvvar("GIT_EMAIL")))

            for p in project:
                popen("git config user.name  %s" % git_username, cwd=p.path)
                popen("git config user.email %s" % git_email, cwd=p.path)

                _, output, _ = popen("git status -s", output=True)

                if output:
                    branch = get_timestamp_str(format_="%Y%m%d%H%M%S")
                    popen("git checkout -B %s" % branch, quiet=not verbose)

                    title = "fix(dependencies): Update dependencies to latest"
                    body = ""

                    # TODO: cross-check with "git add" ?
                    files = p.requirements + [p.pipfile]
                    popen("git add %s" % " ".join(files),
                          quiet=not verbose,
                          cwd=p.path)
                    popen("git commit -m '%s'" % title,
                          quiet=not verbose,
                          cwd=p.path)

                    popen("git push origin %s" % branch,
                          quiet=not verbose,
                          cwd=p.path)

                    if not github_reponame:
                        raise ValueError(
                            errstr % ("GitHub Reponame", "--github-reponame",
                                      getenvvar("GITHUB_REPONAME")))
                    if not github_username:
                        raise ValueError(
                            errstr % ("GitHub Username", "--github-username",
                                      getenvvar("GITHUB_USERNAME")))

                    url = "/".join([
                        "https://api.github.com", "repos", github_username,
                        github_reponame, "pulls"
                    ])
                    headers = dict({
                        "Content-Type":
                        "application/json",
                        "Authorization":
                        "token %s" % github_access_token
                    })
                    data = dict(head="%s:%s" % (git_username, branch),
                                base=target_branch,
                                title=title,
                                body=body)

                    # Although there's monkey patch support for the "requests"
                    # library, avoid using the "json" parameter which was
                    # added in requests 2.4.2+
                    response = req.post(url,
                                        data=json.dumps(data),
                                        headers=headers)

                    if response.ok:
                        response = response.json()
                        number = response["number"]

                        url = "/".join(
                            map(str, [
                                "https://github.com", github_username,
                                github_reponame, "pull", number
                            ]))
                        message = "Created a Pull Request at %s" % url

                        cli.echo(cli_format(message, cli.GREEN))
                    else:
                        response.raise_for_status()