Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GitHub support #2

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 82 additions & 60 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,36 +1,25 @@
AutoUpgrade
===========
[![PyPI](https://img.shields.io/pypi/v/autoupgrade-ng.svg)]
(https://pypi.python.org/pypi/autoupgrade-ng)
[![GitHub issues](https://img.shields.io/github/issues/vuolter/autoupgrade.svg)]
(https://github.com/vuolter/autoupgrade/issues)
[![PyPI](https://img.shields.io/pypi/dm/autoupgrade-ng.svg)]
(https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/l/autoupgrade-ng.svg)]
(https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/format/autoupgrade-ng.svg)]
(https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/pyversions/autoupgrade-ng.svg)]
(https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/status/autoupgrade-ng.svg)]
(https://pypi.python.org/pypi/autoupgrade-ng)
[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/WalterPurcaro.svg?style=social)]
(https://twitter.com/intent/tweet?text=Wow:&url=%5Bobject%20Object%5D)

Automatic upgrade of PyPI packages.


Table of contents
-----------------
# AutoUpgrade
[![PyPI](https://img.shields.io/pypi/v/autoupgrade-ng.svg)](https://pypi.python.org/pypi/autoupgrade-ng)
[![GitHub issues](https://img.shields.io/github/issues/vuolter/autoupgrade.svg)](https://github.com/vuolter/autoupgrade/issues)
[![PyPI](https://img.shields.io/pypi/dm/autoupgrade-ng.svg)](https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/l/autoupgrade-ng.svg)](https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/format/autoupgrade-ng.svg)](https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/pyversions/autoupgrade-ng.svg)](https://pypi.python.org/pypi/autoupgrade-ng)
[![PyPI](https://img.shields.io/pypi/status/autoupgrade-ng.svg)](https://pypi.python.org/pypi/autoupgrade-ng)
[![Twitter](https://img.shields.io/twitter/url/https/twitter.com/WalterPurcaro.svg?style=social)](https://twitter.com/intent/tweet?text=Wow:&url=%5Bobject%20Object%5D)

Automatic upgrade of PyPI packages or GitHub repos.


## Table of contents

- [Quick Start](#quick-start)
- [Installation](#installation)
- [Usage](#usage)
- [Licensing](#licensing)


Quick Start
-----------
## Quick Start

from autoupgrade import Package
Package(<packagename>).smartupgrade()
Expand All @@ -50,8 +39,7 @@ Old methods are still supported; you can accomplish the same task calling:
AutoUpgrade('pip').upgrade_if_needed()


Installation
------------
## Installation

pip install autoupgrade-ng

Expand All @@ -60,83 +48,117 @@ sure you have already removed the old [AutoUpgrade package]
(https://pypi.python.org/pypi/autoupgrade) before install this** to avoid an
installation conflict.

The GitHub features are only accessible if the
[PyGithub package](https://github.com/PyGithub/PyGithub) is installed.

Usage
-----
pip install pygithub

### Classes

class Package(__builtin__.object)
## API

**Decription**: Basic package class, holds one package.
### Classes

class AutoUpgrade(__builtin__.object)
#### class autoupgrade.abc.ABCPackage(object)

**Decription**: Legacy class refering to `Package` one.
Abstract class that defines the structure of an `autoupgrade` package.

#### class autoupgrade.pypi.PyPIPackage(autoupgrade.abc.ABCPackage)

### Methods
Basic package class for PyPI, holds one package.

__init__(self, pkg, index=None, verbose=False)

**Decription**: None.

**Arguments**:

- `pkg` (str) name of package.
- `index` (str) alternative index, if not given default from *pip* will be used.
Include full index url _(e.g. https://example.com/simple)_.
Include full index url *(e.g. https://example.com/simple)*.
- `verbose` (bool) print verbose statements.

**Return**: None.

check(self)
#### class autoupgrade.github.GitHubPackage(autoupgrade.abc.ABCPackage)

**Decription**: Check if `pkg` has a later version.
Basic package class for GitHub, holds one repository.

**Arguments**: None.
__init__(self, pkg, user, repo=None, authenticate=(), verbose=False)

**Return**: True if later version exists, else False.
**Arguments**:

restart(self)
- `pkg` (str) name of package.
- `user` (str) name of the GitHub user/organization that the repo belongs to.
- `repo` (None, str) if the repo doesn't match the `pkg` name.
- `authenticate` (tuple) login credentials to login to GitHub (see
[PyGithum package](https://github.com/PyGithub/PyGithub)) this likely will just be
`(<username>, <password>)` or `(<API token>)`
- `verbose` (bool) print verbose statements.

**Decription**: Restart application with same args as it was started.
**Return**: None.

**Arguments**: None.
#### class autoupgrade.package.Package(object)

Basic class used to bundle PyPIPackage and GitHubPackage.

__init__(self, *args, **kwargs)

**Arguments**: provide arguments for `PyPIPackage` **or** `GitHubPackage` and the
applicable package will be created. Alternatively access the class method
corresponding to the package type you wish to initialize
(e.g. `Package.pypi(*args, **kwargs)` versus `Package.github(*args, **kwargs)`.

**Return**: None.

upgrade(self, dependencies=False, prerelease=False, force=False)
#### class autoupgrde.AutoUpgrade(autoupgrade.package.Package)

**Decription**: Upgrade the package unconditionaly.
**(Deprecated, see Package)**

**Arguments**:
- `dependencies` update dependencies if True _(see `pip --no-deps`)_.
- `prerelease` update to pre-release and development versions.
- `force` reinstall all packages even if they are already up-to-date.

**Return**: None.
### Methods for PyPIPackage & GitHubPackage

smartupgrade(self, restart=True, dependencies=False, prerelease=False)

**Decription**: Upgrade the package if there is a later version available.
Upgrade the package if there is a newer version available.

**Arguments**:

- `restart` restart app if True.
- `dependencies` update dependencies if True _(see `pip --no-deps`)_.
- `dependencies` update dependencies if True *(see `pip --no-deps`)*.
- `prerelease` update to pre-release and development versions.

**Return**: None.

upgrade_if_needed(self, restart=True, dependencies=False, prerelease=False)

**Decription**: Legacy method refering to `smartupgrade` one.
**(Deprecated, see smartupgrade)**

upgrade(self, dependencies=False, prerelease=False, force=False)

Upgrade the package unconditionally.

**Arguments**: Same as `smartupgrade`.
**Arguments**:

- `dependencies` update dependencies if True *(see `pip --no-deps`)*.
- `prerelease` update to pre-release and development versions.
- `force` reinstall all packages even if they are already up-to-date.

check(self)

**Return**: Same as `smartupgrade`.
Check if `pkg` has a newer version.

**Arguments**: None.

**Return**: True if a newer version exists, else False.

restart(self)

Restart application with same args as it was started.

**Arguments**: None.

**Return**: None.


Licensing
---------
## Licensing

Please refer to the included [LICENSE](/LICENSE.md) for the extended license.

Expand Down
18 changes: 5 additions & 13 deletions autoupgrade/__init__.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
# -*- coding: utf-8 -*-

from .exceptions import NoVersionsError, PIPError, PkgNotFoundError
from .package import Package
from .utils import normalize_version

from .package import (Package, AutoUpgrade)

# NOTE: Legacy class
class AutoUpgrade(Package):

def upgrade(self, *args, **kwargs):
try:
Package.upgrade(self, *args, **kwargs)
except PIPError:
return False
else:
return True
__all__ = [
"Package",
"AutoUpgrade",
]
88 changes: 88 additions & 0 deletions autoupgrade/abc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-

import sys
import os
from abc import (ABCMeta, abstractmethod)
import pkg_resources

from .utils import ver_to_tuple


class ABCPackage:
# py2 backwards compatible
__metaclass__ = ABCMeta

# deprecated in favor of smartupgrade
def upgrade_if_needed(self, *args, **kwargs):
return self.smartupgrade(*args, **kwargs)

def smartupgrade(self, restart=True, dependencies=False, prerelease=False):
"""
Upgrade the package if there is a later version available.
Args:
restart: restart app if True
dependencies: update package dependencies if True (see pip --no-deps)
prerelease: update to pre-release and development versions
"""
if not self.check():
if self.verbose:
print("Package {} already up-to-date!".format(self.pkg))
return
if self.verbose:
print("Upgrading {} ... (v{} -> v{})".format(
self.pkg,
".".join(map(str, self._get_current())),
".".join(map(str, self._get_newest_version()))))
self.upgrade(dependencies, prerelease, force=False)
if restart:
self.restart()

@abstractmethod
def upgrade(self, dependencies=False, prerelease=False, force=False):
pass

def restart(self):
"""
Restart application with same args as it was started.
Does **not** return
"""
if self.verbose:
print("Restarting {} {} ...".format(sys.executable, sys.argv))
os.execl(sys.executable, *([sys.executable] + sys.argv))

def check(self):
"""
Check if pkg has a later version
Returns true if later version exists
"""
current = self._get_current()
highest = self._get_newest_version()
outdated = highest > current
if self.verbose:
if outdated:
if current == (-1,):
print("{} is not installed!".format(self.pkg))
else:
print("{} current version: {}".format(self.pkg, current))
print("{} latest version: {}".format(self.pkg, highest))
else:
print("{} is up-to-date!".format(self.pkg))
return

def _get_current(self):
try:
current = pkg_resources.get_distribution(self.pkg).version
current = ver_to_tuple(current)
except pkg_resources.DistributionNotFound:
current = (-1,)
return current

@abstractmethod
def _get_newest_version(self):
pass

def __str__(self):
return self.pkg

def __repr__(self):
return "{}({})".format(self.__class__.__name__, str(self))
Loading