Package: lastversion
lastversionEnglish |简体中文A tiny command-line utility that helps to answer a simple question:What is the lateststableversion for a project?... and, optionally, download/install it.lastversionallows finding well-formatted, the latest release version of a project from these
supported locations:GitHubGitLabBitBucketPyPIMercurialSourceForgeWikipediaWordPress plugin directoryArbitrary software sites which publish releases in RSS/ATOM feedsWhy you needlastversionIn general, quite many project authors complicate finding the latest version by:Creating a formal release that is clearly a Release Candidate (rcin tag), but forgetting to
mark it as a pre-releasePutting extraneous text in release tag e.g.release-1.2.3orname-1.2.3-2019anything fancy
like thatPutting or not putting thevprefix inside release tags. Today yes, tomorrow not. I'm not
consistent about it myself :)Switching from one version format to another, e.g.v20150121tov2.0.1There is no consistency in human beings.To deal with all this mess and simply get a well-formatted, laststableversion (or download
URL!) on the command line, you can uselastversion.Its primary use is for build systems - whenever you want to watch specific projects for released
versions to build packages automatically.
Or otherwise require getting the latest version in your automation scripts.Like I dolastversiondoes a little bit of AI to detect if releasers mistakenly filed a beta version as a
stable release.
It incorporates logic for cleaning up human inconsistency from
version information.Synopsislastversionapache/incubator-pagespeed-ngx#> 1.13.35.2lastversiondownloadapache/incubator-pagespeed-ngx#> downloaded incubator-pagespeed-ngx-v1.13.35.2-stable.tar.gzlastversiondownloadapache/incubator-pagespeed-ngx-opagespeed.tar.gz#> downloads with chosen filenamelastversionhttps://transmissionbt.com/#> 3.0lastversionformat"mysqld  Ver 5.6.51-91.0 for Linux"#> 5.6.51Installation for RPM-based systemsSupported:CentOS/RHEL 7, 8, 9 including clones like AlmaLinux and Rocky LinuxAmazon Linux 2Fedora Linuxsudoyum-yinstallhttps://extras.getpagespeed.com/release-latest.rpm
sudoyum-yinstalllastversionInstallation for other systemsInstalling withpipis easiest:pipinstalllastversionUsageTypically, you would just pass a repository URL (or repo owner/name to it) as the only argument,
e.g.:lastversionhttps://github.com/gperftools/gperftoolsEquivalently accepted invocation with the same output is:lastversiongperftools/gperftoolsIf you're lazy to even copy-paste a project's URL, you can just type its name as argument, which
will use repository search API (slower).
Helps to answer what is the latest Linux version:lastversionlinuxOr wondering what is the latest version of WordPress?lastversionwordpressA special value ofselffor the main argument, will look up the last release oflastversionitself.For more options to control output or behavior, see--helpoutput:usage: lastversion [-h] [--pre] [--sem {major,minor,patch,any}] [-v]
                   [-d [FILENAME]] [--format {version,assets,source,json,tag}]
                   [--assets] [--source] [-gt VER] [-b MAJOR] [--only REGEX]
                   [--exclude REGEX] [--filter REGEX] [--having-asset [ASSET]]
                   [-su] [--even]
                   [--at {github,gitlab,bitbucket,pip,hg,sf,website-feed,local,helm_chart,wiki,system,wp,gitea}]
                   [-y] [--version]
                   [{get,download,extract,unzip,test,format,install,update-spec}]
                   <repo URL or string>

Find the latest software release.

positional arguments:
  {get,download,extract,unzip,test,format,install,update-spec}
                        Action to run. Default: get
  <repo URL or string>  Repository in format owner/name or any URL that
                        belongs to it, or a version string

optional arguments:
  -h, --help            show this help message and exit
  --pre                 Include pre-releases in potential versions
  --sem {major,minor,patch,any}
                        Semantic versioning level base to print or compare
                        against
  -v, --verbose         Will give you an idea of what is happening under the
                        hood, -vv to increase verbosity level
  -d [FILENAME], -o [FILENAME], --download [FILENAME], --output [FILENAME]
                        Download with custom filename
  --format {version,assets,source,json,tag}
                        Output format
  --assets              Returns assets download URLs for last release
  --source              Returns only source URL for last release
  -gt VER, --newer-than VER
                        Output only if last version is newer than given
                        version
  -b MAJOR, --major MAJOR, --branch MAJOR
                        Only consider releases of a specific major version,
                        e.g. 2.1.x
  --only REGEX          Only consider releases containing this text. Useful
                        for repos with multiple projects inside
  --exclude REGEX       Only consider releases NOT containing this text.
                        Useful for repos with multiple projects inside
  --even                Only even versions like 1.[2].x, or 3.[6].x are
                        considered as stable                        
  --filter REGEX        Filters --assets result by a regular expression
  --having-asset [ASSET]
                        Only consider releases with this asset
  -su, --shorter-urls   A tiny bit shorter URLs produced
  --at {github,gitlab,bitbucket,pip,hg,sf,website-feed,local,helm_chart,wiki,system,wp,gitea}
                        If the repo argument is one word, specifies where to
                        look up the project. The default is via internal
                        lookup or GitHub Search
  -y, --assumeyes       Automatically answer yes for all questions
  --version             show program's version number and exitThe--formatwill affect what kind of information from the last release and in which format will
be displayed, e.g.:versionis the default. Simply outputs well-formatted version number of the latest releaseassetswill output a newline-separated list of assets URLs (if any), otherwise link to
sources archivesourcewill output link to source archive, no matter if the release has some assets addedjsoncan be used by external Python modules or for debugging, it is dict/JSON output of an API
call that satisfied last version checkstagwill emit just the latest release's tag name, which useful if you're constructing download
URL yourself or need the tag name otherwiseAn asset is a downloadable file that typically represents an executable, or otherwise
"ready to launch" project. It's what you see filed under formal releases, and is usually a compiled
(for a specific platform), program.Source files are either tarballs or zipballs of sources for the source code of release.You can display either assets or source URLs of the latest release, by passing the corresponding--format flag, e.g.--format sourceYou also simply pass--sourceinstead of--format source, and--assetsinstead of--format assets, as in:lastversion--assetsmautic/mautic#> https://github.com/mautic/mautic/archive/2.15.1/mautic-2.15.1.tar.gzBy default,lastversionfilters output of--assetsto be OS-specific. Who needs.exeon Linux?To override this behavior, you can use--filter, which has a regular expression as its argument.
To disable OS filtering, use--filter ., this will match everything.You can naturally use--filterin place where you would usegrep, e.g.lastversion --assets --filter win REPOUse case: Work with a multi-project repositorySometimes a single repository actually hosts many components, and creates releases that
have separate version line for each component.To helplastversionget a component's version for such repos, use--onlyand--excludeswitches.
They makelastversionlook at only those releases which are tagged (or not) with specified
strings.Example:lastversion--onlycharthttps://github.com/lastversion-test-repos/autoscalerThe above will report9.16.0.lastversion--excludecharthttps://github.com/lastversion-test-repos/autoscalerThe above will report a non-chart latest version,1.23.0.Useful for hard cases, you can pass in regular expressions for both arguments, by prepending them
with tilde, like so:lastversion--only'~-po.-'https://github.com/lastversion-test-repos/autoscalerThe above will consider only releases tagged with -pod-, or -pov-, etc.Use case: How to download the latest version of somethingYou can also uselastversionto download assets/sources for the latest release.Download the most recent Mautic source release:lastversiondownloadmautic/mauticCustomize downloaded filename (works only for sources, which is the default):lastversiondownloadmautic/mautic-omautic.tar.gzYou can also directly fetch and extract the latest release's file into the current working directory
by usingextractcommand:lastversionextractwordpressYou can havelastversionoutput sources/assets URLs and have those downloaded by
something else:wget$(lastversion--assetsmautic/mautic)This will download all assets of the newest stable Mautic, which are two zip files.How this works:lastversionoutputs all asset URLs, each on a new line, andwgetis smart
enough to download each URL. Magic :)For releases that have no assets added, it will download the source archive.To always download the source, use--sourceinstead:wget$(lastversion--sourcemautic/mautic)Use case: Download specific asset under specified filenameIf you want to download specific asset of the last version's release and save the downloaded file
under a desired name, combine-doption (for download name) and--filterfor specifying assets
filter.Example:lastversion--preAircoookie/WLED--formatassets--filterESP32.bin-dESP32.binUse case: Get the last version (betas are fine)We consider the latest release is the one that is stable / not marked as beta.
If you think otherwise, then pass--preswitch and if the latest version of repository is a
pre-release, then you'll get its version instead:lastversion--premautic/mautic#> 2.15.2b0Use case: version of a specific branchFor some projects, there may be several stable releases available simultaneously, in different
branches. An obvious example is PHP. You can use--majorflag to specify the major release
version to match with, to help you find the latest stable release of a branch, like so:lastversionphp/php-src--major7.2This will give you current stable version of PHP 7.2.x, e.g.7.2.28.Branch selector is easy to be specified after semicolon, and together with the search API,
a clean invocation for the same would be:lastversionphp:7.2The branch selector can also be used to get specific release details, e.g.:lastversionphp:7.2.33--assetsUse case: releases with specific assetsSometimes a project makes nice formal releases but delay in uploading assets for releases.
And you might be interested in specific asset type always.
Then you can makelastversionconsider as latest only the last release with specific asset name.
Easy with the--having-assetswitch:lastversiontelegramdesktop/tdesktop--having-asset"Linux 64 bit: Binary"The argument value to--having-assetcan be made as regular expression. For this, prepend it
with tilde sign. E.g. to get releases with macOS installers:lastversiontelegramdesktop/tdesktop--having-asset"~\.dmg$"You can pass no value to--having-assetat all. Thenlastversionwill only return the latest
release which hasanyassets added to it:lastversiontelegramdesktop/tdesktop--having-assetUse case: version of an operating systemThe operating systems are usuallynotversioned through GitHub releases or such.
It is a challenge to get the last stable version of an OS other than from its website,
or other announcement channels.An easy compromise thatlastversiondoes about this, is hard coding well-known OS names, and using
Wikipedia behind the scenes:lastversionrocky#> 8.4lastversionwindows#> 10.0.19043.1081lastversionios#> 14.6You can supply a fully qualified URL to a Wikipedia page for an OS/software project to get version
from there, e.g.:lastversionhttps://en.wikipedia.org/wiki/Rocky_Linux#> 8.4Special use case: NGINX stable vs mainline branch versionlastversionhttps://nginx.org--majorstable#> 1.16.1lastversionhttps://nginx.org--majormainline#> 1.17.9Behind the scenes, this checks withhg.nginx.orgwhich is a Mercurial web repo.
Those are supported as well, e.g.lastversionhttps://hg.example.com/project/Mercurial repositories are rather rare these days, but support has been added primarily for NGINX.Special use case: find the release of a PyPI projectMost Python libraries/apps are hosted on PyPI. To check versions of a project on PyPI, you can use:lastversionhttps://pypi.org/project/requests/If you prefer using a shorter repo name, ensure--at pipswitch, like so:lastversionrequests--atpipInstall an RPM assetIf a project provides.rpmassets and your system hasyumordnf, you can install the project's
RPM directly, like so:sudolastversioninstallmailspringThis findsMailSpring, gets its latest release info,
filters assets for.rpmand passes it toyum/dnf.You can even set up an auto-updater cron job which will ensure you are on the latest version of a
package, like so:@daily/usr/bin/lastversioninstallmailspring-y2>/dev/nullIf the Mailspring GitHub repo posts a release with newer.rpm, then it will be automatically
installed, making sure you are running the latest and greatest Mailspring version.You'll even get an email alert after update (standard cron feature).Needless to say, more often than not, such RPM packages have no idea about all potentially missing
dependencies. Thus, only uselastversion install ...if the software is missing from the baseyumrepositories.Install an AppImageIf a project provides.AppImage, you can install those directly usinglastversion.
TheAppImageis self-contained Linux executable file. Whatlastversiondoes for you, is fetch
the latest release'sAppImage, installs it under~/Applications/<app>and makes it executable.
Just run:lastversioninstallfluent-readerTest version parserThetestcommand can be used for troubleshooting or simply well formatting a string with version:lastversiontest'blah-1.2.3-devel'# > 1.2.3.dev0lastversiontest'1.2.x'# > False (no clear version)lastversiontest'1.2.3-rc1'# > 1.2.3rc1Scripting withlastversioninbashSemantic versioning supportSometimes you only want to check updates for a specific semantic versioning level.
Does a project have a new minor release? Does a project have a new major release?
To print just the necessary semantic versioning base, use--semoption.Acceptable values aremajor,minor, andpatch.lastversionwordpress--semmajor#> 5lastversionwordpress--semminor#> 5.9lastversionwordpress--sempatch#> 5.9.3The value--sem patchcan be used tonormalizea given result to semantic versioning,
if a project doesn't follow the semantics strictly. E.g. sometimes WordPress would publish an x.y
release while it's implicitly x.y.0. So let's say WordPress released "5.10":lastversionwordpress--sempatch#> 5.10.0Format any version stringSay you ranmysqld --versionand got this output:mysqld  Ver 5.6.51-91.0 for Linux on x86_64 (Percona Server (GPL), Release 91.0, Revision b59139e)This is rather hard to parse in bash if you want to just extract the major MySQL server version.lastversioncan easily parse out and give the desired information based on desired semantic
versioning level:lastversion--semmajorformat"mysqld  Ver 5.6.51-91.0 for Linux on x86_64 (Percona Server (GPL) , Release 91.0, Revision b59139e)"#> 5Compare arbitrary versionsUselastversionfor easy comparison of versions on the command line.
Compare two versions, the command will output the highest version:lastversion1.2.3-gt1.2.4#> 1.2.4See the exit codes below, to find whether the first argument is a higher version, or the second.The--semoption described earlier will affect both what's being printed and what semantic
versioning base level is being compared, thus the result.Check for NEW releaseWhen you're building some upstream package, and you did this before, there is a known "last build"
version.
Automatic builds become easy with:CURRENTLY_BUILT_VER=1.2.3# stored somewhere, e.g. spec file in my caseLAST_VER=$(lastversionrepo/owner-gt${CURRENTLY_BUILT_VER})if[[$?-eq0]];then# LAST_VER is newer, update and trigger build# ....fiHere, the-gtis actually a switch passed tolastversion, which acts in a similar fashion to-gtcomparison in bash.There is more to it if you want to make this reliable.
See my ranting onRPM auto-builds withlastversionCheck if there is a newer kernel for your Linux machineLATEST_KERNEL=$(lastversionlinux-gt$(uname-r|cut-d'-'-f1))if[[$?-eq0]];thenecho"I better update my kernel now, because${LATEST_KERNEL}is there"elseecho"My kernel is latest and greatest."fiExit Status codesExit status codes are the usual means of communicating a command's execution success or failure.
Solastversionfollows this: successful command returns0while anything else is an error of
some kind.
For example, when the latest stable release version if found,0is returned.0is also returned for-gtcomparison when leftmost argument is newer than rightmost argument.Exit status code1is returned for cases like no release tag existing for repository at all, or
repository does not exist.Exit status code2is returned for-gtversion comparison negative lookup, that is when rightmost argument is newer
than leftmost argument.Exit status code3is returned when filtering assets of last release yields empty URL set
(no match)TipsGetting the latest version is heavy on the API, because GitHub does not allow to fetch tags in
chronological order, and some repositories switch from one version format to another, sowe can't
just consider the highest version to be latest.
We have to fetch every tag's commit date, and see if it's actually more recent. Thus, it's slower
with larger repositories, which have potentially a lot of tags.Thus,lastversionmakes use of caching API response to be fast and light on GitHub API,
It does conditional ETag validation, which, as per GitHub API will not count towards rate limit.
The cache is stored in~/.cache/lastversionon Linux systems.It ismuch recommendedto set up yourGitHub API token.
Bare API token is enough, you may deselect all permissions.
You can then increase your rate limit by adding the following~/.bashrcfile:exportGITHUB_API_TOKEN=xxxxxxxxxxxxxxxYou can use eitherGITHUB_API_TOKENorGITHUB_TOKENenvironment variable.
The former has priority.For GitLab, you can use aPersonal Access Token:exportGITLAB_PA_TOKEN=xxxxxxxxxxxxxxxThen runsource ~/.bashrc. After this,lastversionwill use it to get larger API calls allowance
from GitHub.Usage in a Python moduleYou can uselastversion.has_update(...)to find whether an update for existing version of
something is available, simply:fromlastversionimporthas_updatelatest_version=has_update(repo="mautic/mautic",current_version='1.2.3')iflatest_version:print(f'Newer Mautic version is available:{latest_version}')else:print('No update is available')Thelastversion.has_update(...)function accepts any URL from a repository (or its short name
, e.g.owner/name) and you should pass an existing/current version.If you are checking version of a project on PyPi, supply an additionalat='pip'argument,
in order to avoid passing the full PyPI URI of a project, and remove ambiguity with GitHub hosted
projects. For example, checking for newer Requests
library:fromlastversionimporthas_updatelatest_version=has_update(repo="requests",at='pip',current_version='1.2.3')iflatest_version:print('Newer Requests library is available:{latest_version}')else:print('No update is available')Thehas_updatefunction returns either:TheVersionobjectFalseif there is no newer version than the one givenAlternatively, invokelastversion.latest(...)function to get the latest version information
for a repo.fromlastversionimportlatestfrompackagingimportversionlatest_mautic_version=latest("mautic/mautic",output_format='version',pre_ok=True)print(f'Latest Mautic version:{latest_mautic_version}')iflatest_mautic_version>=version.parse('1.8.1'):print('It is newer')Withoutput_format='version'(the default), the function returns aVersionobject, orNone. So you can do things like above, namely version comparison, checking dev status, etc.Withoutput_format='dict', a dictionary returned with the latest release information, orFalse.
The dictionary keys vary between different project locations (GitHub vs BitBucket, for example),
but are guaranteed to always have these keys:version:Versionobject, contains the found release version, e.g.1.2.3source: string, the identifier of the project source, e.g.github, orgitlabtag_date: datetime object, the release date, e.g.2020-12-15 14:41:39from: string, contains fully qualified URL of the projecttag_name: string, version control tag name corresponding to the releaseThelastversion.latestfunction accepts 3 argumentsrepo, in format of<owner>/<name>, or any URL under this repository, e.g.https://github.com/dvershinin/lastversion/issuesformat, which accepts the same values as when you runlastversioninteractively, as well asdictto return a dictionary as described abovepre_ok, boolean for whether to include pre-releases as potential versionsat, specifies project location when using one-word repo names, one ofgithub,gitlab,bitbucket,pip,hg,sf,website-feed,localUsing in Continuous IntegrationYou can also uselastversiondirectly in your GitHub action workflows,
withlastversion-action.Sponsored MessageGetPageSpeed RPM Repository: Enhance your server performance with our NGINX modules and performance tools. VisitGetPageSpeed.comto learn more and subscribe for access.