-
-
Notifications
You must be signed in to change notification settings - Fork 34
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
f1e1cd7
commit bd7e32f
Showing
3 changed files
with
113 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
/.idea |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,59 @@ | ||
# whatversion | ||
# lastversion | ||
|
||
A tiny command line utility that helps to answer one simple question: | ||
|
||
> What is the latest released version for a GitHub project? | ||
GitHub has an API endpoint [here](https://developer.github.com/v3/repos/releases/#get-the-latest-release). But if you're here, then you know how it sucks. | ||
|
||
A release would show up in this API response *only* if it was filed formally using GitHub release interface. | ||
Thus, you can find many (if not most) GitHub projects whose Releases are simply not visible through the API, but only through the actual Releases page. | ||
|
||
But we want to get last version on the command line, without looking at Releases page :). Meet `lastversion`. | ||
|
||
## Synopsys | ||
|
||
./lastversion.py apache/incubator-pagespeed-ngx | ||
|
||
> 1.13.35.2 | ||
That repository specifically, is a good example. Because using only API on it will yield an ancient release. | ||
|
||
./lastversion.py --nosniff apache/incubator-pagespeed-ngx | ||
|
||
> 1.9.32.10 | ||
Why is because at some point the maintainers of the repository did a formal UI release, but later used the standard approach. | ||
|
||
|
||
## Usage | ||
|
||
``` | ||
usage: lastversion.py [-h] [--nosniff] [--novalidate] R | ||
Get latest release from GitHub. | ||
positional arguments: | ||
R GitHub repository in format owner/name | ||
optional arguments: | ||
-h, --help show this help message and exit | ||
--nosniff | ||
--novalidate | ||
``` | ||
|
||
The `--nosniff` will disable the magic and only API will be used (yuck). | ||
|
||
The `--novalidate` will disable validation of fetched version. | ||
|
||
### Installation for CentOS 7 | ||
|
||
yum install python-beautifulsoup4 python2-packaging | ||
|
||
yum install ... <I'll package this stuff later> :) | ||
|
||
## Installation for other systems | ||
|
||
The script requires Python 2.7 and few dependencies. | ||
|
||
Review the source file, install dependencies and download `lastversion.py` for running on your system. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
#!/usr/bin/python | ||
|
||
import requests, argparse, sys | ||
from bs4 import BeautifulSoup | ||
from packaging.version import Version, InvalidVersion | ||
|
||
parser = argparse.ArgumentParser(description='Get latest release from GitHub.') | ||
parser.add_argument('repo', metavar='R', | ||
help='GitHub repository in format owner/name') | ||
parser.add_argument('--nosniff', dest='sniff', action='store_false') | ||
parser.add_argument('--novalidate', dest='validate', action='store_false') | ||
parser.set_defaults(sniff=True, validate=True) | ||
args = parser.parse_args() | ||
|
||
repo = args.repo | ||
|
||
version = None | ||
|
||
if args.sniff: | ||
|
||
# Start by fetching HTML of releases page (screw you, Github!) | ||
response = requests.get("https://github.com/{}/releases".format(repo)) | ||
html = response.text | ||
|
||
soup = BeautifulSoup(html, 'html.parser') | ||
|
||
# this tag is known to hold collection of releases not exposed through API | ||
taggedReleases = soup.find(class_='release-timeline-tags') | ||
if taggedReleases: | ||
latest = taggedReleases.find(class_='release-entry') | ||
version = latest.find("a").text.strip() | ||
|
||
if not version: | ||
|
||
r = requests.get('https://api.github.com/repos/{}/releases/latest'.format(repo)) | ||
if r.status_code == 200: | ||
version = r.json()['tag_name'] | ||
else: | ||
sys.stderr.write(r.text) | ||
sys.exit(1) | ||
|
||
# sanitize version tag: | ||
version = version.lstrip("v").rstrip("-beta").rstrip("-stable"); | ||
|
||
if args.validate: | ||
try: | ||
v = Version(version) | ||
except InvalidVersion: | ||
print('Got invalid version: {}'.format(version)) | ||
sys.exit(1) | ||
|
||
# output the version if we've reached far enough: | ||
print(version) |