Ejemplo n.º 1
0
def test_difference():
    assert difference("1.2.3", "2.3.4") == "major"
    assert difference("1.2.3", "1.3.4") == "minor"
    assert difference("1.2.3", "1.2.1") == "patch"
    assert difference("1.2.3", "1.2.3") == None

    with pytest.raises(ValueError):
        difference("1.2.3", "1.0")

    with pytest.raises(ValueError):
        difference("1.2.3.4", "1.2.3.4")

    with pytest.raises(NotImplementedError):
        difference("1.2.3-develop", "1.2.3")
Ejemplo n.º 2
0
def _format_package(package):
    difference = None

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

    string = "* %s" % cli_format(package.name,
                                 _SEMVER_COLOR_MAP.get(difference, cli.CLEAR))

    if getattr(package, "has_dependency_conflict", False):
        string += cli_format(" [dependency conflict]", cli.RED)

    if package.current_version:
        string += " (%s)" % package.current_version

    if package.latest_version and package.current_version != package.latest_version:
        string += " -> (%s)" % _cli_format_semver(package.latest_version,
                                                  difference)

    string += " " + cli_format("[%s]" % package.home_page, cli.CYAN)

    return string
Ejemplo n.º 3
0
    def difference(self):
        difference = None

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

        return difference
Ejemplo n.º 4
0
    def __init__(self, package, sync=False, pip_exec=None):
        logger.info("Initializing Package %s of type %s..." %
                    (package, type(package)))

        self.current_version = None

        if isinstance(package, (_pip.Distribution, _pip.DistInfoDistribution,
                                _pip.EggInfoDistribution)):
            self.name = package.project_name
            self.current_version = package.version
        elif isinstance(package, _pip.InstallRequirement):
            self.name = package.name

            if hasattr(package, "req"):
                if hasattr(package.req, "specifier"):
                    self.current_version = str(package.req.specifier)
            else:
                self.current_version = package.installed_version
        elif isinstance(package, dict):
            self.name = package["name"]
            self.current_version = package["version"]
            self.latest_version = package.get("latest_version")
        elif isinstance(package, str):
            self.name = package
            if pip_exec:
                self.current_version = _get_package_version(package,
                                                            pip_exec=pip_exec)

        res = None

        try:
            logger.info("Fetching package %s information from DB..." %
                        self.name)

            res = _db.query("""
				SELECT *
				FROM `tabPackage`
				WHERE name = '%s'
			""" % self.name)
        except db.OperationalError as e:
            logger.warn("Unable to fetch package name. %s" % e)

        if not res or sync:
            logger.info("Fetching PyPI info for package %s..." % self)
            _pypi_info = _get_pypi_info(self.name, raise_err=False) or {}

            if not hasattr(self, "latest_version"):
                self.latest_version = _pypi_info.get("version")

            self.home_page = _pypi_info.get("home_page")

        if not res:
            try:
                logger.info("Attempting to INSERT package %s into database." %
                            self)

                _db.query("""
					INSERT INTO `tabPackage`
						(name, latest_version, home_page, _created_at)
					VALUES
						('%s', '%s', '%s', '%s')
				""" % (self.name, self.latest_version, self.home_page, datetime.now()))
            except (db.IntegrityError, db.OperationalError) as e:
                logger.warn("Unable to save package name. %s" % e)
        else:
            if sync:
                logger.info(
                    "Attempting to UPDATE package %s within database." % self)

                try:
                    _db.query("""
						UPDATE `tabPackage`
							SET latest_version = '%s', home_page = '%s', _updated_at = '%s'
						WHERE
							name = '%s'
					""" % (self.latest_version, self.home_page, datetime.now(), self.name))
                except db.OperationalError as e:
                    logger.warn("Unable to update package name. %s" % e)
            else:
                logger.info("Using cached info for package %s." % self)

                self.latest_version = res["latest_version"]
                self.home_page = res["home_page"]

        self.dependency_tree = TreeNode(self)

        try:
            self.difference = semver.difference(self.current_version,
                                                self.latest_version)
        except (TypeError, ValueError):
            self.difference = None
Ejemplo n.º 5
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))
Ejemplo n.º 6
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()