Import Upstream version 1.7
This commit is contained in:
parent
ed8521761a
commit
f8c46ef62e
|
@ -16,7 +16,7 @@
|
|||
|
||||
#define DEBIAN
|
||||
#define CSV_NAME "debian"
|
||||
#define CSV_HEADER "version,codename,series,created,release,eol"
|
||||
#define CSV_HEADER "version,codename,series,created,release,eol,eol-lts,eol-elts"
|
||||
#define DISTRO_NAME "Debian"
|
||||
#define NAME "debian-distro-info"
|
||||
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
distro-info (0.23-ok2) yangtze; urgency=low
|
||||
|
||||
* update version info
|
||||
|
||||
-- luzhiping <luzhiping@kylinos.cn> Mon, 22 Aug 2022 13:53:06 +0800
|
||||
|
||||
distro-info (0.23-ok1) yangtze; urgency=low
|
||||
|
||||
* Build for openKylin.
|
||||
|
||||
-- openKylinBot <openKylinBot@openkylin.com> Mon, 25 Apr 2022 22:03:04 +0800
|
|
@ -1,51 +0,0 @@
|
|||
Source: distro-info
|
||||
Section: devel
|
||||
Priority: optional
|
||||
Maintainer: Openkylin Developers <packaging@lists.openkylin.top>
|
||||
XSBC-Original-Maintainer: Benjamin Drung <bdrung@debian.org>
|
||||
Uploaders: Stefano Rivera <stefanor@debian.org>
|
||||
Build-Depends: debhelper-compat (= 12),
|
||||
dh-python,
|
||||
distro-info-data (>= 0.39ubuntu0),
|
||||
pylint (>= 2.2.2-0),
|
||||
python3-all,
|
||||
python3-flake8,
|
||||
python3-setuptools,
|
||||
shunit2 (>= 2.1.6)
|
||||
Standards-Version: 4.4.0
|
||||
Rules-Requires-Root: no
|
||||
Vcs-Git: https://salsa.debian.org/debian/distro-info.git
|
||||
Vcs-Browser: https://salsa.debian.org/debian/distro-info
|
||||
|
||||
Package: distro-info
|
||||
Architecture: any
|
||||
Depends: distro-info-data (>= 0.39ubuntu0), ${misc:Depends}, ${shlibs:Depends}
|
||||
Suggests: shunit2 (>= 2.1.6)
|
||||
Breaks: ubuntu-dev-tools (<< 0.133~)
|
||||
Replaces: ubuntu-dev-tools (<< 0.127~)
|
||||
Description: provides information about the distributions' releases
|
||||
Information about all releases of Debian and Ubuntu. The distro-info script
|
||||
will give you the codename for e.g. the latest stable release of your
|
||||
distribution. To get information about a specific distribution there are the
|
||||
debian-distro-info and the ubuntu-distro-info scripts.
|
||||
|
||||
Package: libdistro-info-perl
|
||||
Architecture: all
|
||||
Section: perl
|
||||
Depends: distro-info-data, ${misc:Depends}, ${perl:Depends}
|
||||
Description: information about distributions' releases (Perl module)
|
||||
Information about all releases of Debian and Ubuntu.
|
||||
.
|
||||
This package contains a Perl module for parsing the data in distro-info-data.
|
||||
There is also a command line interface in the distro-info package.
|
||||
|
||||
Package: python3-distro-info
|
||||
Architecture: all
|
||||
Section: python
|
||||
Depends: distro-info-data, ${misc:Depends}, ${python3:Depends}
|
||||
Description: information about distributions' releases (Python 3 module)
|
||||
Information about all releases of Debian and Ubuntu.
|
||||
.
|
||||
This package contains a Python 3 module for parsing the data in
|
||||
distro-info-data. There is also a command line interface in the distro-info
|
||||
package.
|
|
@ -1,25 +0,0 @@
|
|||
Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: distro-info
|
||||
Upstream-Contact: Benjamin Drung <bdrung@debian.org>
|
||||
|
||||
Files: *
|
||||
Copyright: 2009-2018, Benjamin Drung <bdrung@debian.org>
|
||||
2010-2011, Stefano Rivera <stefanor@debian.org>
|
||||
License: ISC
|
||||
|
||||
Files: shell/*-distro-info.in shell/distro-info-util.sh
|
||||
Copyright: 2012 Canonical Ltd.
|
||||
License: ISC
|
||||
|
||||
License: ISC
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
|
@ -1,2 +0,0 @@
|
|||
usr/bin
|
||||
usr/share/man
|
|
@ -1 +0,0 @@
|
|||
usr/share/perl5
|
|
@ -1 +0,0 @@
|
|||
usr/lib/python3
|
|
@ -1,6 +0,0 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
|
||||
|
||||
%:
|
||||
dh $@ --with python3
|
|
@ -1 +0,0 @@
|
|||
3.0 (native)
|
|
@ -1,15 +0,0 @@
|
|||
Test-Command: COMMAND=/usr/bin/debian-distro-info ./test-debian-distro-info
|
||||
Depends: distro-info, shunit2 (>= 2.1.6)
|
||||
Features: test-name=test-debian-distro-info
|
||||
|
||||
Test-Command: COMMAND=/usr/bin/ubuntu-distro-info ./test-ubuntu-distro-info
|
||||
Depends: distro-info, shunit2 (>= 2.1.6)
|
||||
Features: test-name=test-ubuntu-distro-info
|
||||
|
||||
Test-Command: cp -r python/distro_info_test python/*-distro-info python/setup.py "$AUTOPKGTEST_TMP"; for py in $(py3versions -r 2>/dev/null); do cd "$AUTOPKGTEST_TMP"; echo "Testing with $py:"; $py -m unittest discover -v; done
|
||||
Depends: pylint (>= 2.2.2-2~) | pylint3,
|
||||
python3-all,
|
||||
python3-distro-info,
|
||||
python3-flake8
|
||||
Restrictions: allow-stderr
|
||||
Features: test-name=python3-unittest
|
|
@ -17,6 +17,7 @@
|
|||
// C standard libraries
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
@ -38,6 +39,10 @@
|
|||
static char *milestones[] = {"created"
|
||||
,"release"
|
||||
,"eol"
|
||||
#ifdef DEBIAN
|
||||
,"eol-lts"
|
||||
,"eol-elts"
|
||||
#endif
|
||||
#ifdef UBUNTU
|
||||
,"eol-server"
|
||||
,"eol-esm"
|
||||
|
@ -165,6 +170,37 @@ static date_t *read_date(const char *s, int *failures, const char *filename,
|
|||
return date;
|
||||
}
|
||||
|
||||
// Return current date. Take SOURCE_DATE_EPOCH into account.
|
||||
// The result needs to be freed after its use.
|
||||
static date_t *get_current_date() {
|
||||
char *source_date_epoch, *endptr;
|
||||
date_t *date;
|
||||
unsigned long long epoch;
|
||||
struct tm *now;
|
||||
time_t time_now = 0;
|
||||
|
||||
source_date_epoch = getenv("SOURCE_DATE_EPOCH");
|
||||
if (source_date_epoch != NULL) {
|
||||
epoch = strtoull(source_date_epoch, &endptr, 10);
|
||||
if (epoch > 0 && epoch < ULONG_MAX && *endptr == '\0') {
|
||||
time_now = epoch;
|
||||
} else {
|
||||
fprintf(stderr, NAME ": Environment variable SOURCE_DATE_EPOCH"
|
||||
"='%s' not a valid epoch. Ignoring.\n", source_date_epoch);
|
||||
}
|
||||
}
|
||||
if (time_now == 0) {
|
||||
time_now = time(NULL);
|
||||
}
|
||||
now = gmtime(&time_now);
|
||||
|
||||
date = malloc(sizeof(date_t));
|
||||
date->year = 1900 + now->tm_year;
|
||||
date->month = 1 + now->tm_mon;
|
||||
date->day = now->tm_mday;
|
||||
return date;
|
||||
}
|
||||
|
||||
static inline bool date_ge(const date_t *date1, const date_t *date2) {
|
||||
return date1->year > date2->year ||
|
||||
(date1->year == date2->year && date1->month > date2->month) ||
|
||||
|
@ -194,6 +230,20 @@ static inline bool eol(const date_t *date, const distro_t *distro) {
|
|||
;
|
||||
}
|
||||
|
||||
#ifdef DEBIAN
|
||||
static inline bool eol_lts(const date_t *date, const distro_t *distro) {
|
||||
return !distro->milestones[MILESTONE_EOL_LTS] ||
|
||||
date_ge(date, distro->milestones[MILESTONE_EOL_LTS])
|
||||
;
|
||||
}
|
||||
|
||||
static inline bool eol_elts(const date_t *date, const distro_t *distro) {
|
||||
return !distro->milestones[MILESTONE_EOL_ELTS] ||
|
||||
date_ge(date, distro->milestones[MILESTONE_EOL_ELTS])
|
||||
;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UBUNTU
|
||||
static inline bool eol_esm(const date_t *date, const distro_t *distro) {
|
||||
return distro->milestones[MILESTONE_EOL] &&
|
||||
|
@ -220,6 +270,16 @@ static bool filter_supported(const date_t *date, const distro_t *distro) {
|
|||
return created(date, distro) && !eol(date, distro);
|
||||
}
|
||||
|
||||
#ifdef DEBIAN
|
||||
static bool filter_lts_supported(const date_t *date, const distro_t *distro) {
|
||||
return created(date, distro) && eol(date, distro) && !eol_lts(date, distro);
|
||||
}
|
||||
|
||||
static bool filter_elts_supported(const date_t *date, const distro_t *distro) {
|
||||
return created(date, distro) && eol_lts(date, distro) && !eol_elts(date, distro);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UBUNTU
|
||||
static bool filter_esm_supported(const date_t *date, const distro_t *distro) {
|
||||
return created(date, distro) && !eol_esm(date, distro) &&
|
||||
|
@ -391,6 +451,10 @@ static void free_data(distro_elem_t *list, char **content) {
|
|||
free(list->distro->milestones[MILESTONE_CREATED]);
|
||||
free(list->distro->milestones[MILESTONE_RELEASE]);
|
||||
free(list->distro->milestones[MILESTONE_EOL]);
|
||||
#ifdef DEBIAN
|
||||
free(list->distro->milestones[MILESTONE_EOL_LTS]);
|
||||
free(list->distro->milestones[MILESTONE_EOL_ELTS]);
|
||||
#endif
|
||||
#ifdef UBUNTU
|
||||
free(list->distro->milestones[MILESTONE_EOL_SERVER]);
|
||||
free(list->distro->milestones[MILESTONE_EOL_ESM]);
|
||||
|
@ -417,9 +481,9 @@ static distro_elem_t *read_data(const char *filename, char **content) {
|
|||
data = *content = read_full_file(filename);
|
||||
line = strsep(&data, "\n");
|
||||
lineno = 1;
|
||||
if(unlikely(strcmp(CSV_HEADER, line) != 0)) {
|
||||
fprintf(stderr, NAME ": Header `%s' in file `%s' does not match "
|
||||
"exactly `" CSV_HEADER "'.\n", line, filename);
|
||||
if(unlikely(strncmp(CSV_HEADER, line, strlen(CSV_HEADER)) != 0)) {
|
||||
fprintf(stderr, NAME ": Header `%s' in file `%s' does not start with "
|
||||
"`" CSV_HEADER "'.\n", line, filename);
|
||||
failures++;
|
||||
}
|
||||
|
||||
|
@ -545,19 +609,23 @@ static void print_help(void) {
|
|||
#endif
|
||||
" -a --all list all known versions\n"
|
||||
" -d --devel latest development version\n"
|
||||
#ifdef DEBIAN
|
||||
" -t --testing current testing version\n"
|
||||
#endif
|
||||
" -s --stable latest stable version\n"
|
||||
#ifdef UBUNTU
|
||||
" --lts latest long term support (LTS) version\n"
|
||||
#endif
|
||||
#ifdef DEBIAN
|
||||
" -o --oldstable latest oldstable version\n"
|
||||
#endif
|
||||
" -s --stable latest stable version\n"
|
||||
" --supported list of all supported stable versions\n"
|
||||
" --supported list of all supported versions (including development)\n"
|
||||
#ifdef DEBIAN
|
||||
" -l --lts list of all LTS supported versions\n"
|
||||
" -e --elts list of all Extended LTS supported versions\n"
|
||||
#endif
|
||||
#ifdef UBUNTU
|
||||
" --supported-esm list of all Ubuntu Advantage supported stable versions\n"
|
||||
#endif
|
||||
#ifdef DEBIAN
|
||||
" -t --testing current testing version\n"
|
||||
#endif
|
||||
" --unsupported list of all unsupported stable versions\n"
|
||||
" -c --codename print the codename (default)\n"
|
||||
|
@ -573,9 +641,13 @@ static inline int not_exactly_one(void) {
|
|||
"--alias, "
|
||||
#endif
|
||||
"--all, --devel, "
|
||||
#ifdef UBUNTU
|
||||
"--latest, --lts, "
|
||||
#ifdef DEBIAN
|
||||
"--elts, "
|
||||
#endif
|
||||
#ifdef UBUNTU
|
||||
"--latest, "
|
||||
#endif
|
||||
"--lts, "
|
||||
#ifdef DEBIAN
|
||||
"--oldstable, "
|
||||
#endif
|
||||
|
@ -633,6 +705,8 @@ int main(int argc, char *argv[]) {
|
|||
{"release", no_argument, NULL, 'r' },
|
||||
#ifdef DEBIAN
|
||||
{"alias", required_argument, NULL, 'A' },
|
||||
{"elts", no_argument, NULL, 'e' },
|
||||
{"lts", no_argument, NULL, 'l' },
|
||||
{"oldstable", no_argument, NULL, 'o' },
|
||||
{"testing", no_argument, NULL, 't' },
|
||||
#endif
|
||||
|
@ -647,7 +721,7 @@ int main(int argc, char *argv[]) {
|
|||
const char *short_options = "hadscrfly::";
|
||||
#endif
|
||||
#ifdef DEBIAN
|
||||
const char *short_options = "hadscrfoty::";
|
||||
const char *short_options = "hadescrfloty::";
|
||||
#endif
|
||||
|
||||
// Suppress error messages from getopt_long
|
||||
|
@ -757,6 +831,18 @@ int main(int argc, char *argv[]) {
|
|||
#endif
|
||||
|
||||
#ifdef DEBIAN
|
||||
case 'e':
|
||||
selected_filters++;
|
||||
filter_cb = filter_elts_supported;
|
||||
select_cb = NULL;
|
||||
break;
|
||||
|
||||
case 'l':
|
||||
selected_filters++;
|
||||
filter_cb = filter_lts_supported;
|
||||
select_cb = NULL;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
selected_filters++;
|
||||
filter_cb = filter_oldstable;
|
||||
|
@ -870,12 +956,7 @@ int main(int argc, char *argv[]) {
|
|||
}
|
||||
|
||||
if(unlikely(date == NULL)) {
|
||||
time_t time_now = time(NULL);
|
||||
struct tm *now = gmtime(&time_now);
|
||||
date = malloc(sizeof(date_t));
|
||||
date->year = 1900 + now->tm_year;
|
||||
date->month = 1 + now->tm_mon;
|
||||
date->day = now->tm_mday;
|
||||
date = get_current_date();
|
||||
}
|
||||
|
||||
distro_list = read_data(DATA_DIR "/" CSV_NAME ".csv", &content);
|
||||
|
|
|
@ -34,6 +34,10 @@
|
|||
enum MILESTONE {MILESTONE_CREATED
|
||||
,MILESTONE_RELEASE
|
||||
,MILESTONE_EOL
|
||||
#ifdef DEBIAN
|
||||
,MILESTONE_EOL_LTS
|
||||
,MILESTONE_EOL_ELTS
|
||||
#endif
|
||||
#ifdef UBUNTU
|
||||
,MILESTONE_EOL_SERVER
|
||||
,MILESTONE_EOL_ESM
|
||||
|
@ -71,6 +75,10 @@ static inline bool date_ge(const date_t *date1, const date_t *date2);
|
|||
static inline bool created(const date_t *date, const distro_t *distro);
|
||||
static inline bool released(const date_t *date, const distro_t *distro);
|
||||
static inline bool eol(const date_t *date, const distro_t *distro);
|
||||
#ifdef DEBIAN
|
||||
static inline bool eol_lts(const date_t *date, const distro_t *distro);
|
||||
static inline bool eol_elts(const date_t *date, const distro_t *distro);
|
||||
#endif
|
||||
#ifdef UBUNTU
|
||||
static inline bool eol_esm(const date_t *date, const distro_t *distro);
|
||||
#endif
|
||||
|
|
|
@ -21,7 +21,8 @@ debian\-distro\-info \- provides information about Debian's distributions
|
|||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-date\fR=\fIDATE
|
||||
date for calculating the version (default: today)
|
||||
date for calculating the version (default: epoch taken from SOURCE_DATE_EPOCH
|
||||
environment variable if set, otherwise today)
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
display help message and exit
|
||||
|
@ -63,7 +64,7 @@ series to calculate the version for
|
|||
latest stable version
|
||||
.TP
|
||||
\fB\-\-supported\fR
|
||||
list of all supported stable versions
|
||||
list of all supported versions, including development releases
|
||||
.TP
|
||||
\fB\-t\fR, \fB\-\-testing\fR
|
||||
latest testing version
|
||||
|
|
|
@ -31,7 +31,8 @@ specific.
|
|||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-date\fR=\fIDATE
|
||||
date for calculating the version (default: today)
|
||||
date for calculating the version (default: epoch taken from SOURCE_DATE_EPOCH
|
||||
environment variable if set, otherwise today)
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
display help message and exit
|
||||
|
@ -61,7 +62,7 @@ series to calculate the version for
|
|||
latest stable version
|
||||
.TP
|
||||
\fB\-\-supported\fR
|
||||
list of all supported stable versions
|
||||
list of all supported versions, including development releases
|
||||
.TP
|
||||
\fB\-\-unsupported\fR
|
||||
list of all unsupported stable versions
|
||||
|
|
|
@ -21,7 +21,8 @@ ubuntu\-distro\-info \- provides information about Ubuntu's distributions
|
|||
.SH OPTIONS
|
||||
.TP
|
||||
\fB\-\-date\fR=\fIDATE
|
||||
date for calculating the version (default: today)
|
||||
date for calculating the version (default: epoch taken from SOURCE_DATE_EPOCH
|
||||
environment variable if set, otherwise today)
|
||||
.TP
|
||||
\fB\-h\fR, \fB\-\-help\fR
|
||||
display help message and exit
|
||||
|
@ -64,7 +65,10 @@ series to calculate the version for
|
|||
latest stable version
|
||||
.TP
|
||||
\fB\-\-supported\fR
|
||||
list of all supported stable versions
|
||||
list of all supported versions, including the development release
|
||||
.TP
|
||||
\fB\-\-supported\-esm\fR
|
||||
list of all Ubuntu Advantage supported stable versions
|
||||
.TP
|
||||
\fB\-\-unsupported\fR
|
||||
list of all unsupported stable versions
|
||||
|
|
|
@ -21,7 +21,6 @@ import System.Console.GetOpt
|
|||
import System.Environment
|
||||
import System.Exit
|
||||
import System.IO
|
||||
import System.Locale
|
||||
|
||||
import Text.CSV
|
||||
|
||||
|
@ -47,8 +46,8 @@ startOptions = do
|
|||
|
||||
onlyOneFilter :: a
|
||||
onlyOneFilter = error ("You have to select exactly one of --all, " ++
|
||||
"--devel, --oldstable, --stable, --supported, " ++
|
||||
"--testing, --unsupported.")
|
||||
"--devel, --elts, --lts, --oldstable, --stable, " ++
|
||||
"--supported, --testing, --unsupported.")
|
||||
|
||||
options :: [OptDescr (Options -> IO Options)]
|
||||
options =
|
||||
|
@ -61,7 +60,7 @@ options =
|
|||
then version
|
||||
else debSeries e
|
||||
readDate arg opt =
|
||||
return opt { optDate = readTime defaultTimeLocale "%F" arg }
|
||||
return opt { optDate = parseTimeOrError False defaultTimeLocale "%F" arg }
|
||||
printHelp _ =
|
||||
do
|
||||
prg <- getProgName
|
||||
|
@ -81,14 +80,18 @@ options =
|
|||
"list all known versions"
|
||||
, Option "d" ["devel"] (NoArg (setFilter debianDevel))
|
||||
"latest development version"
|
||||
, Option "o" ["oldstable"] (NoArg (setFilter debianOldstable))
|
||||
"latest oldstable version"
|
||||
, Option "s" ["stable"] (NoArg (setFilter debianStable))
|
||||
"latest stable version"
|
||||
, Option "" ["supported"] (NoArg (setFilter debianSupported))
|
||||
"list of all supported stable versions"
|
||||
, Option "t" ["testing"] (NoArg (setFilter debianTesting))
|
||||
"current testing version"
|
||||
, Option "s" ["stable"] (NoArg (setFilter debianStable))
|
||||
"latest stable version"
|
||||
, Option "o" ["oldstable"] (NoArg (setFilter debianOldstable))
|
||||
"latest oldstable version"
|
||||
, Option "" ["supported"] (NoArg (setFilter debianSupported))
|
||||
"list of all supported versions (including development)"
|
||||
, Option "l" ["lts"] (NoArg (setFilter debianSupportedLTS))
|
||||
"list of all LTS supported versions"
|
||||
, Option "e" ["elts"] (NoArg (setFilter debianSupportedELTS))
|
||||
"list of all Extended LTS supported versions"
|
||||
, Option "" ["unsupported"] (NoArg (setFilter debianUnsupported))
|
||||
"list of all unsupported stable versions"
|
||||
, Option "c" ["codename"]
|
||||
|
|
|
@ -20,6 +20,8 @@ module DistroInfo (DebianEntry, debVersion, debSeries, debFull,
|
|||
debianOldstable,
|
||||
debianStable,
|
||||
debianSupported,
|
||||
debianSupportedLTS,
|
||||
debianSupportedELTS,
|
||||
debianTesting,
|
||||
debianUnsupported,
|
||||
UbuntuEntry, ubuVersion, ubuSeries, ubuFull,
|
||||
|
@ -29,6 +31,7 @@ module DistroInfo (DebianEntry, debVersion, debSeries, debFull,
|
|||
ubuntuLTS,
|
||||
ubuntuStable,
|
||||
ubuntuSupported,
|
||||
ubuntuSupportedESM,
|
||||
ubuntuUnsupported,
|
||||
) where
|
||||
|
||||
|
@ -46,7 +49,9 @@ data DebianEntry = DebianEntry { debVersion :: String,
|
|||
debSeries :: String,
|
||||
debCreated :: Day,
|
||||
debRelease :: Maybe Day,
|
||||
debEol :: Maybe Day
|
||||
debEol :: Maybe Day,
|
||||
debEolLTS :: Maybe Day,
|
||||
debEolELTS :: Maybe Day
|
||||
} deriving(Eq, Show)
|
||||
|
||||
-- | Represents one Ubuntu release data set
|
||||
|
@ -57,7 +62,8 @@ data UbuntuEntry = UbuntuEntry { ubuVersion :: String,
|
|||
ubuCreated :: Day,
|
||||
ubuRelease :: Day,
|
||||
ubuEol :: Day,
|
||||
ubuEolServer :: Maybe Day
|
||||
ubuEolServer :: Maybe Day,
|
||||
ubuEolESM :: Maybe Day
|
||||
} deriving(Eq, Show)
|
||||
|
||||
-- | Splits a string by a given character (similar to the Python split function)
|
||||
|
@ -104,6 +110,7 @@ ubuntuEntry (heading : content) =
|
|||
(convertDate $ m ! "created") (convertDate $ m ! "release")
|
||||
(convertDate $ m ! "eol")
|
||||
(maybeDate $ Map.lookup "eol-server" m)
|
||||
(maybeDate $ Map.lookup "eol-esm" m)
|
||||
|
||||
-- | Converts a given CSV data into a list of Debian entries
|
||||
debianEntry :: CSV -> [DebianEntry]
|
||||
|
@ -117,6 +124,8 @@ debianEntry (heading : content) =
|
|||
(convertDate $ m ! "created")
|
||||
(maybeDate $ Map.lookup "release" m)
|
||||
(maybeDate $ Map.lookup "eol" m)
|
||||
(maybeDate $ Map.lookup "eol-lts" m)
|
||||
(maybeDate $ Map.lookup "eol-elts" m)
|
||||
|
||||
-------------------
|
||||
-- Debian Filter --
|
||||
|
@ -161,6 +170,22 @@ debianSupported date = filter isSupported
|
|||
isSupported DebianEntry { debCreated = created, debEol = eol } =
|
||||
date >= created && maybe True (date <=) eol
|
||||
|
||||
-- | Get list of all LTS supported distributions based on the given date.
|
||||
debianSupportedLTS :: Day -> [DebianEntry] -> [DebianEntry]
|
||||
debianSupportedLTS date = filter isSupportedLTS
|
||||
where
|
||||
isSupportedLTS DebianEntry { debCreated = created, debEol = eol,
|
||||
debEolLTS = eol_lts } =
|
||||
date >= created && maybe False (date >) eol && maybe False (date <=) eol_lts
|
||||
|
||||
-- | Get list of all ELTS supported distributions based on the given date.
|
||||
debianSupportedELTS :: Day -> [DebianEntry] -> [DebianEntry]
|
||||
debianSupportedELTS date = filter isSupportedELTS
|
||||
where
|
||||
isSupportedELTS DebianEntry { debCreated = created, debEolLTS = eol_lts,
|
||||
debEolELTS = eol_elts } =
|
||||
date >= created && maybe False (date >) eol_lts && maybe False (date <=) eol_elts
|
||||
|
||||
-- | Get latest testing Debian distribution based on the given date.
|
||||
debianTesting :: Day -> [DebianEntry] -> [DebianEntry]
|
||||
debianTesting date = filter isUnreleased
|
||||
|
@ -225,6 +250,13 @@ ubuntuSupported date = filter isSupported
|
|||
ubuEolServer = eolServer } =
|
||||
date >= created && (date <= eol || maybe False (date <=) eolServer)
|
||||
|
||||
-- | Get list of all ESM supported distributions based on the given date.
|
||||
ubuntuSupportedESM :: Day -> [UbuntuEntry] -> [UbuntuEntry]
|
||||
ubuntuSupportedESM date = filter isSupportedESM
|
||||
where
|
||||
isSupportedESM UbuntuEntry { ubuCreated = created, ubuEolESM = eolESM } =
|
||||
date >= created && maybe False (date <=) eolESM
|
||||
|
||||
-- | Get list of all unsupported distributions based on the given date.
|
||||
ubuntuUnsupported :: Day -> [UbuntuEntry] -> [UbuntuEntry]
|
||||
ubuntuUnsupported date = filter isUnsupported
|
||||
|
|
|
@ -26,6 +26,10 @@ import DistroInfo
|
|||
|
||||
date1 :: Day
|
||||
date1 = fromGregorian 2011 01 10
|
||||
date2 :: Day
|
||||
date2 = fromGregorian 2016 02 28
|
||||
date3 :: Day
|
||||
date3 = fromGregorian 2020 06 29
|
||||
|
||||
------------------
|
||||
-- Debian tests --
|
||||
|
@ -62,6 +66,18 @@ testDebianSupported d = TestCase (assertEqual "Debian supported" expected result
|
|||
expected = ["lenny", "squeeze", "sid", "experimental"]
|
||||
result = map debSeries $ debianSupported date1 d
|
||||
|
||||
testDebianSupportedLTS :: [DebianEntry] -> Test
|
||||
testDebianSupportedLTS d = TestCase (assertEqual "Debian LTS" expected result)
|
||||
where
|
||||
expected = ["squeeze"]
|
||||
result = map debSeries $ debianSupportedLTS date2 d
|
||||
|
||||
testDebianSupportedELTS :: [DebianEntry] -> Test
|
||||
testDebianSupportedELTS d = TestCase (assertEqual "Debian ELTS" expected result)
|
||||
where
|
||||
expected = ["wheezy"]
|
||||
result = map debSeries $ debianSupportedELTS date3 d
|
||||
|
||||
testDebianTesting :: [DebianEntry] -> Test
|
||||
testDebianTesting d = TestCase (assertEqual "Debian testing" expected result)
|
||||
where
|
||||
|
@ -111,6 +127,12 @@ testUbuntuSupported u = TestCase (assertEqual "Ubuntu supported" expected result
|
|||
expected = ["dapper", "hardy", "karmic", "lucid", "maverick", "natty"]
|
||||
result = map ubuSeries $ ubuntuSupported date1 u
|
||||
|
||||
testUbuntuSupportedESM :: [UbuntuEntry] -> Test
|
||||
testUbuntuSupportedESM u = TestCase (assertEqual "Ubuntu ESM" expected result)
|
||||
where
|
||||
expected = ["precise", "trusty", "xenial"]
|
||||
result = map ubuSeries $ ubuntuSupportedESM date2 u
|
||||
|
||||
testUbuntuUnsupported :: [UbuntuEntry] -> Test
|
||||
testUbuntuUnsupported u = TestCase (assertEqual "Ubuntu unsupported" expected result)
|
||||
where
|
||||
|
@ -126,6 +148,8 @@ tests :: [DebianEntry] -> [UbuntuEntry] -> Test
|
|||
tests d u = TestList [
|
||||
testDebianAll d,
|
||||
testDebianDevel d,
|
||||
testDebianSupportedLTS d,
|
||||
testDebianSupportedELTS d,
|
||||
testDebianOldstable d,
|
||||
testDebianStable d,
|
||||
testDebianSupported d,
|
||||
|
@ -136,6 +160,7 @@ tests d u = TestList [
|
|||
testUbuntuLTS u,
|
||||
testUbuntuStable u,
|
||||
testUbuntuSupported u,
|
||||
testUbuntuSupportedESM u,
|
||||
testUbuntuUnsupported u
|
||||
]
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ import System.Console.GetOpt
|
|||
import System.Environment
|
||||
import System.Exit
|
||||
import System.IO
|
||||
import System.Locale
|
||||
|
||||
import Text.CSV
|
||||
|
||||
|
@ -47,13 +46,14 @@ startOptions = do
|
|||
|
||||
onlyOneFilter :: a
|
||||
onlyOneFilter = error ("You have to select exactly one of --all, --devel, " ++
|
||||
"--lts, --stable, --supported, --unsupported.")
|
||||
"--lts, --stable, --supported, --supported-esm, " ++
|
||||
"--unsupported.")
|
||||
|
||||
options :: [OptDescr (Options -> IO Options)]
|
||||
options =
|
||||
let
|
||||
readDate arg opt =
|
||||
return opt { optDate = readTime defaultTimeLocale "%F" arg }
|
||||
return opt { optDate = parseTimeOrError False defaultTimeLocale "%F" arg }
|
||||
printHelp _ =
|
||||
do
|
||||
prg <- getProgName
|
||||
|
@ -73,12 +73,14 @@ options =
|
|||
"list all known versions"
|
||||
, Option "d" ["devel"] (NoArg (setFilter ubuntuDevel))
|
||||
"latest development version"
|
||||
, Option "" ["lts"] (NoArg (setFilter ubuntuLTS))
|
||||
"latest long term support (LTS) version"
|
||||
, Option "s" ["stable"] (NoArg (setFilter ubuntuStable))
|
||||
"latest stable version"
|
||||
, Option "" ["lts"] (NoArg (setFilter ubuntuLTS))
|
||||
"latest long term support (LTS) version"
|
||||
, Option "" ["supported"] (NoArg (setFilter ubuntuSupported))
|
||||
"list of all supported stable versions"
|
||||
"list of all supported versions (including development)"
|
||||
, Option "" ["supported-esm"] (NoArg (setFilter ubuntuSupportedESM))
|
||||
"list of all Ubuntu Advantage supported stable versions"
|
||||
, Option "" ["unsupported"] (NoArg (setFilter ubuntuUnsupported))
|
||||
"list of all unsupported stable versions"
|
||||
, Option "c" ["codename"]
|
||||
|
|
|
@ -77,7 +77,8 @@ sub convert_date {
|
|||
for my $col (@header) {
|
||||
$row{$col} = shift(@raw_row) or undef;
|
||||
}
|
||||
for my $col ('created', 'release', 'eol', 'eol-server', 'eol-esm') {
|
||||
for my $col ('created', 'release', 'eol', 'eol-esm', 'eol-lts',
|
||||
'eol-elts', 'eol-server') {
|
||||
if(defined($row{$col})) {
|
||||
$row{$col} = Debian::DistroInfo::convert_date($row{$col});
|
||||
}
|
||||
|
@ -249,6 +250,32 @@ sub convert_date {
|
|||
return @distros;
|
||||
}
|
||||
|
||||
sub supported_lts {
|
||||
my ($self, $date) = @_;
|
||||
$date = $self->{'date'} if (!defined($date));
|
||||
my @distros;
|
||||
for my $row ($self->_avail($date)) {
|
||||
if (defined($row->{'eol'}) && $date > $row->{'eol'}
|
||||
&& defined($row->{'eol-lts'}) && $date <= $row->{'eol-lts'}) {
|
||||
push(@distros, $row->{'series'});
|
||||
}
|
||||
}
|
||||
return @distros;
|
||||
}
|
||||
|
||||
sub supported_elts {
|
||||
my ($self, $date) = @_;
|
||||
$date = $self->{'date'} if (!defined($date));
|
||||
my @distros;
|
||||
for my $row ($self->_avail($date)) {
|
||||
if (defined($row->{'eol-lts'}) && $date > $row->{'eol-lts'}
|
||||
&& defined($row->{'eol-elts'}) && $date <= $row->{'eol-elts'}) {
|
||||
push(@distros, $row->{'series'});
|
||||
}
|
||||
}
|
||||
return @distros;
|
||||
}
|
||||
|
||||
sub testing {
|
||||
my ($self, $date) = @_;
|
||||
$date = $self->{'date'} if (!defined($date));
|
||||
|
|
51
perl/test.pl
51
perl/test.pl
|
@ -1,5 +1,5 @@
|
|||
#!/usr/bin/perl
|
||||
# Copyright (C) 2011-2012, Stefano Rivera <stefanor@debian.org>
|
||||
# Copyright (C) 2011-2019, Stefano Rivera <stefanor@debian.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -16,7 +16,7 @@
|
|||
use strict;
|
||||
use warnings;
|
||||
|
||||
use Test::Simple tests => 32;
|
||||
use Test::Simple tests => 35;
|
||||
|
||||
use lib '.';
|
||||
use Debian::DistroInfo;
|
||||
|
@ -55,35 +55,47 @@ ok(symmetric_difference(\@all, \@returned) == 1,
|
|||
|
||||
# Test DistroInfo:
|
||||
my @expected = ();
|
||||
my $date = Debian::DistroInfo::convert_date('2011-01-10');
|
||||
my $date1 = Debian::DistroInfo::convert_date('2011-01-10');
|
||||
my $date2 = Debian::DistroInfo::convert_date('2016-02-28');
|
||||
my $date3 = Debian::DistroInfo::convert_date('2020-06-29');
|
||||
|
||||
my $deb = DebianDistroInfo->new();
|
||||
@all = ('buzz', 'rex', 'bo', 'hamm', 'slink', 'potato', 'woody', 'sarge',
|
||||
'etch', 'lenny', 'squeeze', 'sid', 'experimental');
|
||||
@returned = $deb->all($date);
|
||||
@returned = $deb->all($date1);
|
||||
ok(unique(\@all, \@returned) == 0, 'Debian all');
|
||||
|
||||
ok($deb->devel($date) eq 'sid', 'Debian devel');
|
||||
ok($deb->old($date) eq 'etch', 'Debian oldstable');
|
||||
ok($deb->stable($date) eq 'lenny', 'Debian stable');
|
||||
ok($deb->testing($date) eq 'squeeze', 'Debian testing');
|
||||
ok($deb->devel($date1) eq 'sid', 'Debian devel');
|
||||
ok($deb->old($date1) eq 'etch', 'Debian oldstable');
|
||||
ok($deb->stable($date1) eq 'lenny', 'Debian stable');
|
||||
ok($deb->testing($date1) eq 'squeeze', 'Debian testing');
|
||||
ok($deb->valid('sid'), 'Debian valid');
|
||||
ok($deb->valid('stable'), 'Debian valid');
|
||||
ok(!$deb->valid('foobar'), 'Debian invalid');
|
||||
|
||||
@expected = ('lenny', 'squeeze', 'sid', 'experimental');
|
||||
@returned = $deb->supported($date);
|
||||
@returned = $deb->supported($date1);
|
||||
ok(symmetric_difference(\@expected, \@returned) == 0,
|
||||
'Debian supported');
|
||||
|
||||
@expected = ('squeeze');
|
||||
@returned = $deb->supported_lts($date2);
|
||||
ok(symmetric_difference(\@expected, \@returned) == 0,
|
||||
'Debian LTS');
|
||||
|
||||
@expected = ('wheezy');
|
||||
@returned = $deb->supported_elts($date3);
|
||||
ok(symmetric_difference(\@expected, \@returned) == 0,
|
||||
'Debian ELTS');
|
||||
|
||||
@expected = ('buzz', 'rex', 'bo', 'hamm', 'slink', 'potato', 'woody', 'sarge',
|
||||
'etch');
|
||||
@returned = $deb->unsupported($date);
|
||||
@returned = $deb->unsupported($date1);
|
||||
ok(symmetric_difference(\@expected, \@returned) == 0,
|
||||
'Debian unsupported');
|
||||
|
||||
ok(!defined($deb->codename('foo')), 'Debian codename, invalid');
|
||||
ok($deb->codename('testing', $date) eq $deb->testing($date),
|
||||
ok($deb->codename('testing', $date1) eq $deb->testing($date1),
|
||||
'Debian codename');
|
||||
|
||||
ok(!defined($deb->version('foo')), 'Debian version, invalid');
|
||||
|
@ -92,15 +104,15 @@ ok($deb->version('lenny') eq '5.0', 'Debian version');
|
|||
my $ubu = UbuntuDistroInfo->new();
|
||||
@all = ('warty', 'hoary', 'breezy', 'dapper', 'edgy', 'feisty', 'gutsy',
|
||||
'hardy', 'intrepid', 'jaunty', 'karmic', 'lucid', 'maverick', 'natty');
|
||||
@returned = $ubu->all($date);
|
||||
@returned = $ubu->all($date1);
|
||||
ok(unique(\@all, \@returned) == 0, 'Ubuntu all');
|
||||
|
||||
ok($ubu->version('Maverick Meerkat') eq '10.10', 'Ubuntu version');
|
||||
ok($ubu->version('lucid') eq '10.04 LTS', 'Ubuntu LTS version');
|
||||
|
||||
ok($ubu->devel($date) eq 'natty', 'Ubuntu devel');
|
||||
ok($ubu->lts($date) eq 'lucid', 'Ubuntu LTS');
|
||||
ok($ubu->stable($date) eq 'maverick', 'Ubuntu stable');
|
||||
ok($ubu->devel($date1) eq 'natty', 'Ubuntu devel');
|
||||
ok($ubu->lts($date1) eq 'lucid', 'Ubuntu LTS');
|
||||
ok($ubu->stable($date1) eq 'maverick', 'Ubuntu stable');
|
||||
ok($ubu->valid('lucid'), 'Ubuntu valid');
|
||||
ok(!$ubu->valid(42), 'Ubuntu invalid');
|
||||
ok($ubu->is_lts('lucid'), 'Ubuntu is_lts');
|
||||
|
@ -108,13 +120,18 @@ ok(!$ubu->is_lts(42), 'Ubuntu !is_lts');
|
|||
ok(!$ubu->is_lts('warty'), 'Ubuntu !is_lts');
|
||||
|
||||
@expected = ('dapper', 'hardy', 'karmic', 'lucid', 'maverick', 'natty');
|
||||
@returned = $ubu->supported($date);
|
||||
@returned = $ubu->supported($date1);
|
||||
ok(symmetric_difference(\@expected, \@returned) == 0,
|
||||
'Ubuntu supported');
|
||||
|
||||
@expected = ('precise', 'trusty', 'xenial');
|
||||
@returned = $ubu->supported_esm($date2);
|
||||
ok(symmetric_difference(\@expected, \@returned) == 0,
|
||||
'Ubuntu ESM');
|
||||
|
||||
@expected = ('warty', 'hoary', 'breezy', 'edgy', 'feisty', 'gutsy', 'intrepid',
|
||||
'jaunty');
|
||||
@returned = $ubu->unsupported($date);
|
||||
@returned = $ubu->unsupported($date1);
|
||||
ok(symmetric_difference(\@expected, \@returned) == 0,
|
||||
'Ubuntu unsupported');
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (C) 2009-2011, Benjamin Drung <bdrung@debian.org>
|
||||
#
|
||||
|
@ -23,50 +23,89 @@ import argparse
|
|||
import os
|
||||
import sys
|
||||
|
||||
from distro_info import convert_date, DebianDistroInfo
|
||||
from distro_info import DebianDistroInfo, convert_date
|
||||
|
||||
|
||||
def parse_args():
|
||||
script_name = os.path.basename(sys.argv[0])
|
||||
usage = "%s [options]" % (script_name)
|
||||
epilog = "See %s(1) for more info." % (script_name)
|
||||
usage = f"{script_name} [options]"
|
||||
epilog = f"See {script_name}(1) for more info."
|
||||
parser = argparse.ArgumentParser(usage=usage, epilog=epilog)
|
||||
|
||||
parser.add_argument("--date", dest="date", default=None,
|
||||
help="date for calculating the version (default: today).")
|
||||
parser.add_argument("-a", "--all", dest="all", action="store_true",
|
||||
help="list all known versions")
|
||||
parser.add_argument("-d", "--devel", dest="devel", action="store_true",
|
||||
help="latest development version")
|
||||
parser.add_argument("-o", "--old", dest="old", action="store_true",
|
||||
help="latest old (stable) version")
|
||||
parser.add_argument("-s", "--stable", dest="stable", action="store_true",
|
||||
help="latest stable version")
|
||||
parser.add_argument("--supported", dest="supported", action="store_true",
|
||||
help="list of all supported stable versions")
|
||||
parser.add_argument("-t", "--testing", dest="testing", action="store_true",
|
||||
help="current testing version")
|
||||
parser.add_argument("--unsupported", dest="unsupported",
|
||||
help="list of all unsupported stable versions")
|
||||
parser.add_argument(
|
||||
"--date",
|
||||
dest="date",
|
||||
default=None,
|
||||
help="date for calculating the version (default: today).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-a", "--all", dest="all", action="store_true", help="list all known versions"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d", "--devel", dest="devel", action="store_true", help="latest development version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-t", "--testing", dest="testing", action="store_true", help="current testing version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s", "--stable", dest="stable", action="store_true", help="latest stable version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o", "--old", dest="old", action="store_true", help="latest old (stable) version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--supported",
|
||||
dest="supported",
|
||||
action="store_true",
|
||||
help="list of all supported versions (including development)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l",
|
||||
"--lts",
|
||||
dest="lts",
|
||||
action="store_true",
|
||||
help="list of all LTS supported stable versions",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-e",
|
||||
"--elts",
|
||||
dest="elts",
|
||||
action="store_true",
|
||||
help="list of all ELTS supported stable versions",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--unsupported", dest="unsupported", help="list of all unsupported stable versions"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
versions = [args.all, args.devel, args.old, args.stable,
|
||||
args.supported, args.testing, args.unsupported]
|
||||
versions = [
|
||||
args.all,
|
||||
args.devel,
|
||||
args.lts,
|
||||
args.elts,
|
||||
args.old,
|
||||
args.stable,
|
||||
args.supported,
|
||||
args.testing,
|
||||
args.unsupported,
|
||||
]
|
||||
if len([x for x in versions if x]) != 1:
|
||||
parser.error("You have to select exactly one of --all, --devel, --old, "
|
||||
"--stable, --supported, --testing, --unsupported.")
|
||||
parser.error(
|
||||
"You have to select exactly one of --all, --devel, --elts, --lts,"
|
||||
" --old, --stable, --supported, --testing, --unsupported."
|
||||
)
|
||||
|
||||
if args.date is not None:
|
||||
try:
|
||||
args.date = convert_date(args.date)
|
||||
except ValueError:
|
||||
parser.error("Option --date needs to be a date in ISO 8601 "
|
||||
"format.")
|
||||
parser.error("Option --date needs to be a date in ISO 8601 format.")
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
# pylint: disable=too-many-branches
|
||||
args = parse_args()
|
||||
if args.all:
|
||||
for distro in DebianDistroInfo().all:
|
||||
|
@ -80,6 +119,12 @@ def main():
|
|||
elif args.supported:
|
||||
for distro in DebianDistroInfo().supported(args.date):
|
||||
sys.stdout.write(distro + "\n")
|
||||
elif args.lts:
|
||||
for distro in DebianDistroInfo().lts_supported(args.date):
|
||||
sys.stdout.write(distro + "\n")
|
||||
elif args.elts:
|
||||
for distro in DebianDistroInfo().elts_supported(args.date):
|
||||
sys.stdout.write(distro + "\n")
|
||||
elif args.testing:
|
||||
sys.stdout.write(DebianDistroInfo().testing(args.date) + "\n")
|
||||
elif args.unsupported:
|
||||
|
|
|
@ -17,29 +17,24 @@
|
|||
import csv
|
||||
import datetime
|
||||
import os
|
||||
import typing
|
||||
|
||||
|
||||
def convert_date(string):
|
||||
def convert_date(string: str) -> datetime.date:
|
||||
"""Convert a date string in ISO 8601 into a datetime object."""
|
||||
if not string:
|
||||
date = None
|
||||
else:
|
||||
parts = [int(x) for x in string.split("-")]
|
||||
if len(parts) == 3:
|
||||
(year, month, day) = parts
|
||||
date = datetime.date(year, month, day)
|
||||
elif len(parts) == 2:
|
||||
(year, month) = parts
|
||||
if month == 12:
|
||||
date = datetime.date(year, month, 31)
|
||||
else:
|
||||
date = datetime.date(year, month + 1, 1) - datetime.timedelta(1)
|
||||
else:
|
||||
raise ValueError("Date not in ISO 8601 format.")
|
||||
return date
|
||||
parts = [int(x) for x in string.split("-")]
|
||||
if len(parts) == 3:
|
||||
(year, month, day) = parts
|
||||
return datetime.date(year, month, day)
|
||||
if len(parts) == 2:
|
||||
(year, month) = parts
|
||||
if month == 12:
|
||||
return datetime.date(year, month, 31)
|
||||
return datetime.date(year, month + 1, 1) - datetime.timedelta(1)
|
||||
raise ValueError("Date not in ISO 8601 format.")
|
||||
|
||||
|
||||
def _get_data_dir():
|
||||
def _get_data_dir() -> str:
|
||||
"""Get the data directory based on the module location."""
|
||||
return "/usr/share/distro-info"
|
||||
|
||||
|
@ -47,20 +42,32 @@ def _get_data_dir():
|
|||
class DistroDataOutdated(Exception):
|
||||
"""Distribution data outdated."""
|
||||
|
||||
def __init__(self):
|
||||
super(DistroDataOutdated, self).__init__(
|
||||
"Distribution data outdated. "
|
||||
"Please check for an update for distro-info-data. See "
|
||||
"/usr/share/doc/distro-info-data/README.Debian for details.")
|
||||
def __init__(self) -> None:
|
||||
super().__init__(
|
||||
"Distribution data outdated. Please check for an update for distro-info-data. "
|
||||
"See /usr/share/doc/distro-info-data/README.Debian for details."
|
||||
)
|
||||
|
||||
|
||||
class DistroRelease(object):
|
||||
class DistroRelease:
|
||||
"""Represents a distributions release"""
|
||||
|
||||
# pylint: disable=too-few-public-methods
|
||||
# pylint: disable=too-many-instance-attributes
|
||||
|
||||
def __init__(self, version, codename, series, created=None, release=None, eol=None,
|
||||
eol_server=None, eol_esm=None):
|
||||
def __init__(
|
||||
self,
|
||||
version: str,
|
||||
codename: str,
|
||||
series: str,
|
||||
created: datetime.date,
|
||||
release: typing.Optional[datetime.date] = None,
|
||||
eol: typing.Optional[datetime.date] = None,
|
||||
eol_esm: typing.Optional[datetime.date] = None,
|
||||
eol_lts: typing.Optional[datetime.date] = None,
|
||||
eol_elts: typing.Optional[datetime.date] = None,
|
||||
eol_server: typing.Optional[datetime.date] = None,
|
||||
) -> None:
|
||||
# pylint: disable=too-many-arguments
|
||||
self.version = version
|
||||
self.codename = codename
|
||||
|
@ -68,75 +75,102 @@ class DistroRelease(object):
|
|||
self.created = created
|
||||
self.release = release
|
||||
self.eol = eol
|
||||
self.eol_server = eol_server
|
||||
self.eol_lts = eol_lts
|
||||
self.eol_elts = eol_elts
|
||||
self.eol_esm = eol_esm
|
||||
self.eol_server = eol_server
|
||||
|
||||
def is_supported(self, date):
|
||||
def is_supported(self, date: datetime.date) -> bool:
|
||||
"""Check whether this release is supported on the given date."""
|
||||
return date >= self.created and (self.eol is None or date <= self.eol or (
|
||||
self.eol_server is not None and date <= self.eol_server))
|
||||
return date >= self.created and (
|
||||
self.eol is None
|
||||
or date <= self.eol
|
||||
or (self.eol_server is not None and date <= self.eol_server)
|
||||
)
|
||||
|
||||
|
||||
def _get_date(row, column):
|
||||
return convert_date(row[column]) if column in row else None
|
||||
def _get_date(row: dict[str, str], column: str) -> typing.Optional[datetime.date]:
|
||||
date_string = row.get(column)
|
||||
if not date_string:
|
||||
return None
|
||||
return convert_date(date_string)
|
||||
|
||||
|
||||
class DistroInfo(object):
|
||||
class DistroInfo:
|
||||
"""Base class for distribution information.
|
||||
Use DebianDistroInfo or UbuntuDistroInfo instead of using this directly.
|
||||
"""
|
||||
|
||||
def __init__(self, distro):
|
||||
def __init__(self, distro: str) -> None:
|
||||
self._distro = distro
|
||||
filename = os.path.join(_get_data_dir(), distro.lower() + ".csv")
|
||||
csvfile = open(filename)
|
||||
csv_reader = csv.DictReader(csvfile)
|
||||
self._releases = []
|
||||
for row in csv_reader:
|
||||
release = DistroRelease(row['version'], row['codename'], row['series'],
|
||||
_get_date(row, 'created'), _get_date(row, 'release'),
|
||||
_get_date(row, 'eol'), _get_date(row, 'eol-server'),
|
||||
_get_date(row, 'eol-esm'))
|
||||
self._releases.append(release)
|
||||
csvfile.close()
|
||||
with open(filename, encoding="utf-8") as csvfile:
|
||||
csv_reader = csv.DictReader(csvfile)
|
||||
self._releases = []
|
||||
for row in csv_reader:
|
||||
release = DistroRelease(
|
||||
row["version"],
|
||||
row["codename"],
|
||||
row["series"],
|
||||
convert_date(row["created"]),
|
||||
_get_date(row, "release"),
|
||||
_get_date(row, "eol"),
|
||||
_get_date(row, "eol-esm"),
|
||||
_get_date(row, "eol-lts"),
|
||||
_get_date(row, "eol-elts"),
|
||||
_get_date(row, "eol-server"),
|
||||
)
|
||||
self._releases.append(release)
|
||||
self._date = datetime.date.today()
|
||||
|
||||
@property
|
||||
def all(self):
|
||||
def all(self) -> list[str]:
|
||||
"""List codenames of all known distributions."""
|
||||
return [x.series for x in self._releases]
|
||||
|
||||
def get_all(self, result="codename"):
|
||||
def get_all(self, result: str = "codename") -> list[typing.Union[DistroRelease, str]]:
|
||||
"""List all known distributions."""
|
||||
return [self._format(result, x) for x in self._releases]
|
||||
|
||||
def _avail(self, date):
|
||||
def _avail(self, date: datetime.date) -> list[DistroRelease]:
|
||||
"""Return all distributions that were available on the given date."""
|
||||
return [x for x in self._releases if date >= x.created]
|
||||
|
||||
def codename(self, release, date=None, default=None):
|
||||
def codename(
|
||||
self,
|
||||
release: str,
|
||||
date: typing.Optional[datetime.date] = None,
|
||||
default: typing.Optional[str] = None,
|
||||
) -> typing.Union[DistroRelease, str, None]:
|
||||
"""Map codename aliases to the codename they describe."""
|
||||
# pylint: disable=no-self-use,unused-argument
|
||||
return release
|
||||
|
||||
def version(self, name, default=None):
|
||||
def version(self, name: str, default: typing.Optional[str] = None) -> typing.Optional[str]:
|
||||
"""Map codename or series to version"""
|
||||
for release in self._releases:
|
||||
if name in (release.codename, release.series):
|
||||
return release.version
|
||||
return default
|
||||
|
||||
def devel(self, date=None, result="codename"):
|
||||
def devel(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> typing.Union[DistroRelease, str]:
|
||||
"""Get latest development distribution based on the given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [x for x in self._avail(date) if x.release is None or
|
||||
(date < x.release and (x.eol is None or date <= x.eol))]
|
||||
distros = [
|
||||
x
|
||||
for x in self._avail(date)
|
||||
if x.release is None or (date < x.release and (x.eol is None or date <= x.eol))
|
||||
]
|
||||
if not distros:
|
||||
raise DistroDataOutdated()
|
||||
return self._format(result, distros[-1])
|
||||
|
||||
def _format(self, format_string, release):
|
||||
def _format(
|
||||
self, format_string: str, release: DistroRelease
|
||||
) -> typing.Union[DistroRelease, str]:
|
||||
"""Format a given distribution entry."""
|
||||
if format_string == "object":
|
||||
return release
|
||||
|
@ -147,142 +181,217 @@ class DistroInfo(object):
|
|||
if format_string == "release":
|
||||
return release.version
|
||||
|
||||
raise ValueError("Only codename, fullname, object, and release are allowed "
|
||||
"result values, but not '" + format_string + "'.")
|
||||
raise ValueError(
|
||||
"Only codename, fullname, object, and release are allowed "
|
||||
"result values, but not '" + format_string + "'."
|
||||
)
|
||||
|
||||
def stable(self, date=None, result="codename"):
|
||||
def stable(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> typing.Union[DistroRelease, str]:
|
||||
"""Get latest stable distribution based on the given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [x for x in self._avail(date) if x.release is not None and
|
||||
date >= x.release and (x.eol is None or date <= x.eol)]
|
||||
distros = [
|
||||
x
|
||||
for x in self._avail(date)
|
||||
if x.release is not None and date >= x.release and (x.eol is None or date <= x.eol)
|
||||
]
|
||||
if not distros:
|
||||
raise DistroDataOutdated()
|
||||
return self._format(result, distros[-1])
|
||||
|
||||
def supported(self, date=None, result=None):
|
||||
def supported(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> list[typing.Union[DistroRelease, str]]:
|
||||
"""Get list of all supported distributions based on the given date."""
|
||||
raise NotImplementedError()
|
||||
|
||||
def valid(self, codename):
|
||||
def valid(self, codename: str) -> bool:
|
||||
"""Check if the given codename is known."""
|
||||
return codename in self.all
|
||||
|
||||
def unsupported(self, date=None, result="codename"):
|
||||
def unsupported(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> list[typing.Union[DistroRelease, str]]:
|
||||
"""Get list of all unsupported distributions based on the given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
supported = self.supported(date)
|
||||
distros = [self._format(result, x) for x in self._avail(date)
|
||||
if x.series not in supported]
|
||||
distros = [self._format(result, x) for x in self._avail(date) if x.series not in supported]
|
||||
return distros
|
||||
|
||||
|
||||
class DebianDistroInfo(DistroInfo):
|
||||
"""provides information about Debian's distributions"""
|
||||
|
||||
def __init__(self):
|
||||
super(DebianDistroInfo, self).__init__("Debian")
|
||||
def __init__(self) -> None:
|
||||
super().__init__("Debian")
|
||||
|
||||
def codename(self, release, date=None, default=None):
|
||||
def codename(
|
||||
self,
|
||||
release: str,
|
||||
date: typing.Optional[datetime.date] = None,
|
||||
default: typing.Optional[str] = None,
|
||||
) -> typing.Union[DistroRelease, str, None]:
|
||||
"""Map 'unstable', 'testing', etc. to their codenames."""
|
||||
if release == "unstable":
|
||||
codename = self.devel(date)
|
||||
elif release == "testing":
|
||||
codename = self.testing(date)
|
||||
elif release == "stable":
|
||||
codename = self.stable(date)
|
||||
elif release == "oldstable":
|
||||
codename = self.old(date)
|
||||
else:
|
||||
codename = default
|
||||
return codename
|
||||
return self.devel(date)
|
||||
if release == "testing":
|
||||
return self.testing(date)
|
||||
if release == "stable":
|
||||
return self.stable(date)
|
||||
if release == "oldstable":
|
||||
return self.old(date)
|
||||
return default
|
||||
|
||||
def devel(self, date=None, result="codename"):
|
||||
def devel(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> typing.Union[DistroRelease, str]:
|
||||
"""Get latest development distribution based on the given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [x for x in self._avail(date) if x.release is None or
|
||||
(date < x.release and (x.eol is None or date <= x.eol))]
|
||||
distros = [
|
||||
x
|
||||
for x in self._avail(date)
|
||||
if x.release is None or (date < x.release and (x.eol is None or date <= x.eol))
|
||||
]
|
||||
if len(distros) < 2:
|
||||
raise DistroDataOutdated()
|
||||
return self._format(result, distros[-2])
|
||||
|
||||
def old(self, date=None, result="codename"):
|
||||
def old(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> typing.Union[DistroRelease, str]:
|
||||
"""Get old (stable) Debian distribution based on the given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [x for x in self._avail(date)
|
||||
if x.release is not None and date >= x.release]
|
||||
distros = [x for x in self._avail(date) if x.release is not None and date >= x.release]
|
||||
if len(distros) < 2:
|
||||
raise DistroDataOutdated()
|
||||
return self._format(result, distros[-2])
|
||||
|
||||
def supported(self, date=None, result="codename"):
|
||||
def supported(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> list[typing.Union[DistroRelease, str]]:
|
||||
"""Get list of all supported Debian distributions based on the given
|
||||
date."""
|
||||
date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [self._format(result, x) for x in self._avail(date)
|
||||
if x.eol is None or date <= x.eol]
|
||||
distros = [
|
||||
self._format(result, x) for x in self._avail(date) if x.eol is None or date <= x.eol
|
||||
]
|
||||
return distros
|
||||
|
||||
def testing(self, date=None, result="codename"):
|
||||
def lts_supported(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> list[typing.Union[DistroRelease, str]]:
|
||||
"""Get list of all LTS supported Debian distributions based on the given
|
||||
date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [
|
||||
self._format(result, x)
|
||||
for x in self._avail(date)
|
||||
if (x.eol is not None and date > x.eol)
|
||||
and (x.eol_lts is not None and date <= x.eol_lts)
|
||||
]
|
||||
return distros
|
||||
|
||||
def elts_supported(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> list[typing.Union[DistroRelease, str]]:
|
||||
"""Get list of all Extended LTS supported Debian distributions based on
|
||||
the given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [
|
||||
self._format(result, x)
|
||||
for x in self._avail(date)
|
||||
if (x.eol_lts is not None and date > x.eol_lts)
|
||||
and (x.eol_elts is not None and date <= x.eol_elts)
|
||||
]
|
||||
return distros
|
||||
|
||||
def testing(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> typing.Union[DistroRelease, str]:
|
||||
"""Get latest testing Debian distribution based on the given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [x for x in self._avail(date) if (x.release is None and x.version) or
|
||||
(x.release is not None and date < x.release and
|
||||
(x.eol is None or date <= x.eol))]
|
||||
distros = [
|
||||
x
|
||||
for x in self._avail(date)
|
||||
if (x.release is None and x.version)
|
||||
or (x.release is not None and date < x.release and (x.eol is None or date <= x.eol))
|
||||
]
|
||||
if not distros:
|
||||
raise DistroDataOutdated()
|
||||
return self._format(result, distros[-1])
|
||||
|
||||
def valid(self, codename):
|
||||
def valid(self, codename: str) -> bool:
|
||||
"""Check if the given codename is known."""
|
||||
return (DistroInfo.valid(self, codename) or
|
||||
codename in ["unstable", "testing", "stable", "oldstable"])
|
||||
return DistroInfo.valid(self, codename) or codename in [
|
||||
"unstable",
|
||||
"testing",
|
||||
"stable",
|
||||
"oldstable",
|
||||
]
|
||||
|
||||
|
||||
class UbuntuDistroInfo(DistroInfo):
|
||||
"""provides information about Ubuntu's distributions"""
|
||||
|
||||
def __init__(self):
|
||||
super(UbuntuDistroInfo, self).__init__("Ubuntu")
|
||||
def __init__(self) -> None:
|
||||
super().__init__("Ubuntu")
|
||||
|
||||
def lts(self, date=None, result="codename"):
|
||||
def lts(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> typing.Union[DistroRelease, str]:
|
||||
"""Get latest long term support (LTS) Ubuntu distribution based on the
|
||||
given date."""
|
||||
given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [x for x in self._releases if x.version.find("LTS") >= 0 and
|
||||
x.release <= date <= x.eol]
|
||||
distros = [
|
||||
x
|
||||
for x in self._releases
|
||||
if x.version.find("LTS") >= 0 and x.release and x.eol and x.release <= date <= x.eol
|
||||
]
|
||||
if not distros:
|
||||
raise DistroDataOutdated()
|
||||
return self._format(result, distros[-1])
|
||||
|
||||
def is_lts(self, codename):
|
||||
def is_lts(self, codename: str) -> bool:
|
||||
"""Is codename an LTS release?"""
|
||||
distros = [x for x in self._releases if x.series == codename]
|
||||
if not distros:
|
||||
return False
|
||||
return "LTS" in distros[0].version
|
||||
|
||||
def supported(self, date=None, result="codename"):
|
||||
def supported(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> list[typing.Union[DistroRelease, str]]:
|
||||
"""Get list of all supported Ubuntu distributions based on the given
|
||||
date."""
|
||||
date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [self._format(result, x) for x in self._avail(date)
|
||||
if date <= x.eol or
|
||||
(x.eol_server is not None and date <= x.eol_server)]
|
||||
distros = [
|
||||
self._format(result, x)
|
||||
for x in self._avail(date)
|
||||
if (x.eol and date <= x.eol) or (x.eol_server is not None and date <= x.eol_server)
|
||||
]
|
||||
return distros
|
||||
|
||||
def supported_esm(self, date=None, result="codename"):
|
||||
def supported_esm(
|
||||
self, date: typing.Optional[datetime.date] = None, result: str = "codename"
|
||||
) -> list[typing.Union[DistroRelease, str]]:
|
||||
"""Get list of all ESM supported Ubuntu distributions based on the
|
||||
given date."""
|
||||
given date."""
|
||||
if date is None:
|
||||
date = self._date
|
||||
distros = [self._format(result, x) for x in self._avail(date)
|
||||
if x.eol_esm is not None and date <= x.eol_esm]
|
||||
distros = [
|
||||
self._format(result, x)
|
||||
for x in self._avail(date)
|
||||
if x.eol_esm is not None and date <= x.eol_esm
|
||||
]
|
||||
return distros
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Copyright (C) 2017, Benjamin Drung <benjamin.drung@profitbricks.com>
|
||||
# Copyright (C) 2017-2021, Benjamin Drung <benjamin.drung@ionos.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
|
@ -12,46 +12,47 @@
|
|||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""Test suite for distro-info"""
|
||||
"""Helper functions for testing."""
|
||||
|
||||
import inspect
|
||||
import os
|
||||
import site
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
|
||||
def get_source_files():
|
||||
"""Return a list of sources files/directories (to check with flake8/pylint)"""
|
||||
def get_source_files() -> list[str]:
|
||||
"""Return a list of sources files/directories (to check with flake8/pylint)."""
|
||||
scripts = ["debian-distro-info", "ubuntu-distro-info"]
|
||||
modules = []
|
||||
modules = ["distro_info_test"]
|
||||
py_files = ["distro_info.py", "setup.py"]
|
||||
|
||||
files = []
|
||||
for code_file in scripts + modules + py_files:
|
||||
is_script = code_file in scripts
|
||||
if not os.path.exists(code_file): # pragma: no cover
|
||||
# The alternative path in the OLDPWD environment is needed for Debian's pybuild
|
||||
# Use installed files as fallback
|
||||
for alternative_path in [os.environ.get("OLDPWD", "")] + site.getsitepackages():
|
||||
alternative = os.path.join(alternative_path, code_file)
|
||||
if os.path.exists(alternative):
|
||||
code_file = alternative
|
||||
break
|
||||
# The alternative path is needed for Debian's pybuild
|
||||
alternative = os.path.join(os.environ.get("OLDPWD", ""), code_file)
|
||||
code_file = alternative if os.path.exists(alternative) else code_file
|
||||
if (
|
||||
not os.path.exists(code_file)
|
||||
and code_file.endswith(".py")
|
||||
and "AUTOPKGTEST_TMP" in os.environ
|
||||
):
|
||||
code_file = "/usr/lib/python3/dist-packages/" + code_file
|
||||
if is_script:
|
||||
with open(code_file, "rb") as script_file:
|
||||
shebang = script_file.readline().decode("utf-8")
|
||||
if ((sys.version_info[0] == 3 and "python3" in shebang)
|
||||
or ("python" in shebang and "python3" not in shebang)):
|
||||
if "python" in shebang:
|
||||
files.append(code_file)
|
||||
else:
|
||||
files.append(code_file)
|
||||
return files
|
||||
|
||||
|
||||
def unittest_verbosity():
|
||||
"""Return the verbosity setting of the currently running unittest
|
||||
program, or None if none is running.
|
||||
def unittest_verbosity() -> int:
|
||||
"""
|
||||
Return the verbosity setting of the currently running unittest.
|
||||
|
||||
If no test is running, return 0.
|
||||
"""
|
||||
frame = inspect.currentframe()
|
||||
while frame:
|
||||
|
@ -59,4 +60,4 @@ def unittest_verbosity():
|
|||
if isinstance(self, unittest.TestProgram):
|
||||
return self.verbosity
|
||||
frame = frame.f_back
|
||||
return None # pragma: no cover
|
||||
return 0 # pragma: no cover
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
[MASTER]
|
||||
[MAIN]
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=no
|
||||
|
||||
load-plugins=pylint.extensions.no_self_use
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
|
@ -15,7 +16,7 @@ persistent=no
|
|||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=locally-disabled,locally-enabled,missing-docstring,useless-object-inheritance
|
||||
disable=locally-disabled,missing-docstring
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
@ -37,4 +38,4 @@ indent-string=' '
|
|||
[SIMILARITIES]
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=11
|
||||
min-similarity-lines=15
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
# Copyright (C) 2021, Benjamin Drung <bdrung@debian.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""Run black code formatter in check mode."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from . import get_source_files, unittest_verbosity
|
||||
|
||||
|
||||
class BlackTestCase(unittest.TestCase):
|
||||
"""
|
||||
This unittest class provides a test that runs the black code
|
||||
formatter in check mode on the Python source code. The list of
|
||||
source files is provided by the get_source_files() function.
|
||||
"""
|
||||
|
||||
def test_black(self) -> None:
|
||||
"""Test: Run black code formatter on Python source code."""
|
||||
cmd = ["black", "--check", "--diff", "-l", "99"] + get_source_files()
|
||||
if unittest_verbosity() >= 2:
|
||||
sys.stderr.write(f"Running following command:\n{' '.join(cmd)}\n")
|
||||
process = subprocess.run(cmd, capture_output=True, check=False, text=True)
|
||||
|
||||
if process.returncode == 1: # pragma: no cover
|
||||
self.fail(f"black found code that needs reformatting:\n{process.stdout.strip()}")
|
||||
if process.returncode != 0: # pragma: no cover
|
||||
self.fail(f"black exited with code {process.returncode}:\n{process.stdout.strip()}")
|
|
@ -25,159 +25,188 @@ from distro_info import DebianDistroInfo, UbuntuDistroInfo
|
|||
class DebianDistroInfoTestCase(unittest.TestCase): # pylint: disable=too-many-public-methods
|
||||
"""TestCase object for distro_info.DebianDistroInfo"""
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
def setUp(self) -> None: # pylint: disable=invalid-name
|
||||
self._distro_info = DebianDistroInfo()
|
||||
self._date = datetime.date(2011, 1, 10)
|
||||
|
||||
def test_all(self):
|
||||
def test_all(self) -> None:
|
||||
"""Test: List all known Debian distributions."""
|
||||
all_distros = set(["buzz", "rex", "bo", "hamm", "slink", "potato",
|
||||
"woody", "sarge", "etch", "lenny", "squeeze", "sid",
|
||||
"experimental"])
|
||||
all_distros = {
|
||||
"buzz",
|
||||
"rex",
|
||||
"bo",
|
||||
"hamm",
|
||||
"slink",
|
||||
"potato",
|
||||
"woody",
|
||||
"sarge",
|
||||
"etch",
|
||||
"lenny",
|
||||
"squeeze",
|
||||
"sid",
|
||||
"experimental",
|
||||
}
|
||||
self.assertEqual(all_distros - set(self._distro_info.all), set())
|
||||
|
||||
def test_devel(self):
|
||||
def test_devel(self) -> None:
|
||||
"""Test: Get latest development Debian distribution."""
|
||||
self.assertEqual(self._distro_info.devel(self._date), "sid")
|
||||
|
||||
def test_old(self):
|
||||
def test_old(self) -> None:
|
||||
"""Test: Get old (stable) Debian distribution."""
|
||||
self.assertEqual(self._distro_info.old(self._date), "etch")
|
||||
|
||||
def test_stable(self):
|
||||
def test_stable(self) -> None:
|
||||
"""Test: Get latest stable Debian distribution."""
|
||||
self.assertEqual(self._distro_info.stable(self._date), "lenny")
|
||||
|
||||
def test_supported(self):
|
||||
def test_supported(self) -> None:
|
||||
"""Test: List all supported Debian distribution."""
|
||||
self.assertEqual(self._distro_info.supported(self._date),
|
||||
["lenny", "squeeze", "sid", "experimental"])
|
||||
self.assertEqual(
|
||||
self._distro_info.supported(self._date), ["lenny", "squeeze", "sid", "experimental"]
|
||||
)
|
||||
|
||||
def test_testing(self):
|
||||
def test_lts_supported(self) -> None:
|
||||
"""Test: List all LTS supported Debian distribution."""
|
||||
date = datetime.date(2016, 2, 28)
|
||||
self.assertEqual(self._distro_info.lts_supported(date), ["squeeze"])
|
||||
|
||||
def test_elts_supported(self) -> None:
|
||||
"""Test: List all ELTS supported Debian distribution."""
|
||||
date = datetime.date(2020, 6, 29)
|
||||
self.assertEqual(self._distro_info.elts_supported(date), ["wheezy"])
|
||||
|
||||
def test_testing(self) -> None:
|
||||
"""Test: Get latest testing Debian distribution."""
|
||||
self.assertEqual(self._distro_info.testing(self._date), "squeeze")
|
||||
|
||||
def test_valid(self):
|
||||
def test_valid(self) -> None:
|
||||
"""Test: Check for valid Debian distribution."""
|
||||
self.assertTrue(self._distro_info.valid("sid"))
|
||||
self.assertTrue(self._distro_info.valid("stable"))
|
||||
self.assertFalse(self._distro_info.valid("foobar"))
|
||||
|
||||
def test_unsupported(self):
|
||||
def test_unsupported(self) -> None:
|
||||
"""Test: List all unsupported Debian distribution."""
|
||||
unsupported = ["buzz", "rex", "bo", "hamm", "slink", "potato", "woody",
|
||||
"sarge", "etch"]
|
||||
unsupported = ["buzz", "rex", "bo", "hamm", "slink", "potato", "woody", "sarge", "etch"]
|
||||
self.assertEqual(self._distro_info.unsupported(self._date), unsupported)
|
||||
|
||||
def test_codename(self):
|
||||
def test_codename(self) -> None:
|
||||
"""Test: Codename decoding"""
|
||||
self.assertIsNone(self._distro_info.codename('foobar'))
|
||||
self.assertEqual(self._distro_info.codename('testing', self._date),
|
||||
self._distro_info.testing(self._date))
|
||||
self.assertIsNone(self._distro_info.codename("foobar"))
|
||||
self.assertEqual(
|
||||
self._distro_info.codename("testing", self._date),
|
||||
self._distro_info.testing(self._date),
|
||||
)
|
||||
|
||||
def test_version(self):
|
||||
def test_version(self) -> None:
|
||||
"""Test: Version decoding"""
|
||||
self.assertIsNone(self._distro_info.version('foobar'))
|
||||
self.assertEqual(self._distro_info.version('lenny'), '5.0')
|
||||
self.assertIsNone(self._distro_info.version("foobar"))
|
||||
self.assertEqual(self._distro_info.version("lenny"), "5.0")
|
||||
|
||||
def test_codename_result(self):
|
||||
def test_codename_result(self) -> None:
|
||||
"""Test: Check result set to codename."""
|
||||
self.assertEqual(self._distro_info.old(self._date, "codename"), "etch")
|
||||
self.assertEqual(self._distro_info.devel(self._date, result="codename"),
|
||||
"sid")
|
||||
self.assertEqual(self._distro_info.devel(self._date, result="codename"), "sid")
|
||||
|
||||
def test_fullname(self):
|
||||
def test_fullname(self) -> None:
|
||||
"""Test: Check result set to fullname."""
|
||||
self.assertEqual(self._distro_info.stable(self._date, "fullname"),
|
||||
'Debian 5.0 "Lenny"')
|
||||
self.assertEqual(self._distro_info.stable(self._date, "fullname"), 'Debian 5.0 "Lenny"')
|
||||
result = self._distro_info.testing(self._date, result="fullname")
|
||||
self.assertEqual(result, 'Debian 6.0 "Squeeze"')
|
||||
|
||||
def test_release(self):
|
||||
def test_release(self) -> None:
|
||||
"""Test: Check result set to release."""
|
||||
self.assertEqual(self._distro_info.devel(self._date, "release"), "")
|
||||
self.assertEqual(self._distro_info.testing(self._date, "release"),
|
||||
"6.0")
|
||||
self.assertEqual(self._distro_info.stable(self._date, result="release"),
|
||||
"5.0")
|
||||
self.assertEqual(self._distro_info.testing(self._date, "release"), "6.0")
|
||||
self.assertEqual(self._distro_info.stable(self._date, result="release"), "5.0")
|
||||
|
||||
|
||||
class UbuntuDistroInfoTestCase(unittest.TestCase): # pylint: disable=too-many-public-methods
|
||||
"""TestCase object for distro_info.UbuntuDistroInfo"""
|
||||
|
||||
def setUp(self): # pylint: disable=invalid-name
|
||||
def setUp(self) -> None: # pylint: disable=invalid-name
|
||||
self._distro_info = UbuntuDistroInfo()
|
||||
self._date = datetime.date(2011, 1, 10)
|
||||
|
||||
def test_all(self):
|
||||
def test_all(self) -> None:
|
||||
"""Test: List all known Ubuntu distributions."""
|
||||
all_distros = set(["warty", "hoary", "breezy", "dapper", "edgy",
|
||||
"feisty", "gutsy", "hardy", "intrepid", "jaunty",
|
||||
"karmic", "lucid", "maverick", "natty"])
|
||||
all_distros = {
|
||||
"warty",
|
||||
"hoary",
|
||||
"breezy",
|
||||
"dapper",
|
||||
"edgy",
|
||||
"feisty",
|
||||
"gutsy",
|
||||
"hardy",
|
||||
"intrepid",
|
||||
"jaunty",
|
||||
"karmic",
|
||||
"lucid",
|
||||
"maverick",
|
||||
"natty",
|
||||
}
|
||||
self.assertEqual(all_distros - set(self._distro_info.all), set())
|
||||
|
||||
def test_devel(self):
|
||||
def test_devel(self) -> None:
|
||||
"""Test: Get latest development Ubuntu distribution."""
|
||||
self.assertEqual(self._distro_info.devel(self._date), "natty")
|
||||
|
||||
def test_lts(self):
|
||||
def test_lts(self) -> None:
|
||||
"""Test: Get latest long term support (LTS) Ubuntu distribution."""
|
||||
self.assertEqual(self._distro_info.lts(self._date), "lucid")
|
||||
|
||||
def test_stable(self):
|
||||
def test_stable(self) -> None:
|
||||
"""Test: Get latest stable Ubuntu distribution."""
|
||||
self.assertEqual(self._distro_info.stable(self._date), "maverick")
|
||||
|
||||
def test_supported(self):
|
||||
def test_supported(self) -> None:
|
||||
"""Test: List all supported Ubuntu distribution."""
|
||||
supported = ["dapper", "hardy", "karmic", "lucid", "maverick", "natty"]
|
||||
self.assertEqual(self._distro_info.supported(self._date), supported)
|
||||
|
||||
def test_unsupported(self):
|
||||
def test_unsupported(self) -> None:
|
||||
"""Test: List all unsupported Ubuntu distributions."""
|
||||
unsupported = ["warty", "hoary", "breezy", "edgy", "feisty", "gutsy",
|
||||
"intrepid", "jaunty"]
|
||||
unsupported = ["warty", "hoary", "breezy", "edgy", "feisty", "gutsy", "intrepid", "jaunty"]
|
||||
self.assertEqual(self._distro_info.unsupported(self._date), unsupported)
|
||||
|
||||
def test_current_unsupported(self):
|
||||
def test_current_unsupported(self) -> None:
|
||||
"""Test: List all unsupported Ubuntu distributions today."""
|
||||
unsupported = set(["warty", "hoary", "breezy", "edgy", "feisty",
|
||||
"gutsy", "intrepid", "jaunty"])
|
||||
self.assertEqual(unsupported -
|
||||
set(self._distro_info.unsupported()), set())
|
||||
unsupported = {"warty", "hoary", "breezy", "edgy", "feisty", "gutsy", "intrepid", "jaunty"}
|
||||
self.assertEqual(unsupported - set(str(d) for d in self._distro_info.unsupported()), set())
|
||||
|
||||
def test_valid(self):
|
||||
def test_valid(self) -> None:
|
||||
"""Test: Check for valid Ubuntu distribution."""
|
||||
self.assertTrue(self._distro_info.valid("lucid"))
|
||||
self.assertFalse(self._distro_info.valid("42"))
|
||||
|
||||
def test_is_lts(self):
|
||||
def test_is_lts(self) -> None:
|
||||
"""Test: Check if Ubuntu distribution is an LTS."""
|
||||
self.assertTrue(self._distro_info.is_lts("lucid"))
|
||||
self.assertFalse(self._distro_info.is_lts("42"))
|
||||
self.assertFalse(self._distro_info.is_lts("warty"))
|
||||
|
||||
def test_codename(self):
|
||||
def test_codename(self) -> None:
|
||||
"""Test: Check result set to codename."""
|
||||
self.assertEqual(self._distro_info.lts(self._date, "codename"), "lucid")
|
||||
self.assertEqual(self._distro_info.devel(self._date, result="codename"),
|
||||
"natty")
|
||||
self.assertEqual(self._distro_info.devel(self._date, result="codename"), "natty")
|
||||
|
||||
def test_version(self):
|
||||
def test_version(self) -> None:
|
||||
"""Test: Check result set to version."""
|
||||
self.assertEqual(self._distro_info.version("lucid"), '10.04 LTS')
|
||||
self.assertEqual(self._distro_info.version("Maverick Meerkat"), '10.10')
|
||||
self.assertEqual(self._distro_info.version("lucid"), "10.04 LTS")
|
||||
self.assertEqual(self._distro_info.version("Maverick Meerkat"), "10.10")
|
||||
|
||||
def test_fullname(self):
|
||||
def test_fullname(self) -> None:
|
||||
"""Test: Check result set to fullname."""
|
||||
self.assertEqual(self._distro_info.stable(self._date, "fullname"),
|
||||
'Ubuntu 10.10 "Maverick Meerkat"')
|
||||
self.assertEqual(self._distro_info.lts(self._date, result="fullname"),
|
||||
'Ubuntu 10.04 LTS "Lucid Lynx"')
|
||||
self.assertEqual(
|
||||
self._distro_info.stable(self._date, "fullname"), 'Ubuntu 10.10 "Maverick Meerkat"'
|
||||
)
|
||||
self.assertEqual(
|
||||
self._distro_info.lts(self._date, result="fullname"), 'Ubuntu 10.04 LTS "Lucid Lynx"'
|
||||
)
|
||||
|
||||
def test_release(self):
|
||||
def test_release(self) -> None:
|
||||
"""Test: Check result set to release."""
|
||||
self.assertEqual(self._distro_info.devel(self._date, "release"),
|
||||
"11.04")
|
||||
self.assertEqual(self._distro_info.lts(self._date, result="release"),
|
||||
"10.04 LTS")
|
||||
self.assertEqual(self._distro_info.devel(self._date, "release"), "11.04")
|
||||
self.assertEqual(self._distro_info.lts(self._date, result="release"), "10.04 LTS")
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""test_flake8.py - Run flake8 check"""
|
||||
"""Run flake8 check."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
|
@ -29,23 +29,25 @@ class Flake8TestCase(unittest.TestCase):
|
|||
get_source_files() function.
|
||||
"""
|
||||
|
||||
def test_flake8(self):
|
||||
"""Test: Run flake8 on Python source code"""
|
||||
cmd = [sys.executable, "-m", "flake8", "--ignore", "H301,H403,H405,W504", "--max-line-length=99"] + get_source_files()
|
||||
def test_flake8(self) -> None:
|
||||
"""Test: Run flake8 on Python source code."""
|
||||
cmd = [sys.executable, "-m", "flake8", "--max-line-length=99"] + get_source_files()
|
||||
if unittest_verbosity() >= 2:
|
||||
sys.stderr.write("Running following command:\n{}\n".format(" ".join(cmd)))
|
||||
process = subprocess.Popen(cmd, stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE, close_fds=True)
|
||||
sys.stderr.write(f"Running following command:\n{' '.join(cmd)}\n")
|
||||
process = subprocess.run(cmd, capture_output=True, check=False, text=True)
|
||||
|
||||
out, err = process.communicate()
|
||||
if process.returncode != 0: # pragma: no cover
|
||||
msgs = []
|
||||
if err:
|
||||
msgs.append("flake8 exited with code {} and has unexpected output on stderr:\n{}"
|
||||
.format(process.returncode, err.decode().rstrip()))
|
||||
if out:
|
||||
msgs.append("flake8 found issues:\n{}".format(out.decode().rstrip()))
|
||||
if process.stderr:
|
||||
msgs.append(
|
||||
f"flake8 exited with code {process.returncode} and has"
|
||||
f" unexpected output on stderr:\n{process.stderr.rstrip()}"
|
||||
)
|
||||
if process.stdout:
|
||||
msgs.append(f"flake8 found issues:\n{process.stdout.rstrip()}")
|
||||
if not msgs:
|
||||
msgs.append("flake8 exited with code {} and has no output on stdout or stderr."
|
||||
.format(process.returncode))
|
||||
msgs.append(
|
||||
f"flake8 exited with code {process.returncode} "
|
||||
"and has no output on stdout or stderr."
|
||||
)
|
||||
self.fail("\n".join(msgs))
|
||||
|
|
|
@ -20,52 +20,60 @@ import select
|
|||
import signal
|
||||
import subprocess
|
||||
import time
|
||||
import typing
|
||||
import unittest
|
||||
|
||||
import setup
|
||||
from distro_info_test import unittest
|
||||
|
||||
TIMEOUT = 5
|
||||
|
||||
|
||||
class HelpTestCase(unittest.TestCase):
|
||||
@classmethod
|
||||
def populate(cls):
|
||||
def populate(cls) -> None:
|
||||
for script in setup.SCRIPTS:
|
||||
setattr(cls, 'test_' + script, cls.make_help_tester(script))
|
||||
setattr(cls, "test_" + script, cls.make_help_tester(script))
|
||||
|
||||
@classmethod
|
||||
def make_help_tester(cls, script):
|
||||
def tester(self):
|
||||
null = open('/dev/null', 'r')
|
||||
process = subprocess.Popen(['./' + script, '--help'],
|
||||
close_fds=True, stdin=null,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE)
|
||||
started = time.time()
|
||||
out = []
|
||||
def make_help_tester(cls, script: str) -> typing.Callable[[typing.Any], None]:
|
||||
def tester(self: typing.Any) -> None:
|
||||
with subprocess.Popen(
|
||||
["./" + script, "--help"],
|
||||
close_fds=True,
|
||||
stdin=subprocess.DEVNULL,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
) as process:
|
||||
started = time.time()
|
||||
out = []
|
||||
|
||||
fds = [process.stdout.fileno(), process.stderr.fileno()]
|
||||
for file_descriptor in fds:
|
||||
fcntl.fcntl(file_descriptor, fcntl.F_SETFL,
|
||||
fcntl.fcntl(file_descriptor, fcntl.F_GETFL) | os.O_NONBLOCK)
|
||||
assert process.stdout
|
||||
assert process.stderr
|
||||
fds = [process.stdout.fileno(), process.stderr.fileno()]
|
||||
for file_descriptor in fds:
|
||||
fcntl.fcntl(
|
||||
file_descriptor,
|
||||
fcntl.F_SETFL,
|
||||
fcntl.fcntl(file_descriptor, fcntl.F_GETFL) | os.O_NONBLOCK,
|
||||
)
|
||||
|
||||
while time.time() - started < TIMEOUT:
|
||||
for file_descriptor in select.select(fds, [], fds, TIMEOUT)[0]:
|
||||
out.append(os.read(file_descriptor, 1024))
|
||||
if process.poll() is not None:
|
||||
break
|
||||
while time.time() - started < TIMEOUT:
|
||||
for file_descriptor in select.select(fds, [], fds, TIMEOUT)[0]:
|
||||
out.append(os.read(file_descriptor, 1024))
|
||||
if process.poll() is not None:
|
||||
break
|
||||
|
||||
if process.poll() is None:
|
||||
os.kill(process.pid, signal.SIGTERM)
|
||||
time.sleep(1)
|
||||
if process.poll() is None:
|
||||
os.kill(process.pid, signal.SIGKILL)
|
||||
null.close()
|
||||
os.kill(process.pid, signal.SIGTERM)
|
||||
time.sleep(1)
|
||||
if process.poll() is None:
|
||||
os.kill(process.pid, signal.SIGKILL)
|
||||
|
||||
self.assertEqual(
|
||||
process.poll(),
|
||||
0,
|
||||
f"{script} failed to return usage within {TIMEOUT} seconds.\n"
|
||||
f"Output:\n{b''.join(out).decode()}",
|
||||
)
|
||||
|
||||
self.assertEqual(process.poll(), 0,
|
||||
"%s failed to return usage within %i seconds.\n"
|
||||
"Output:\n%s"
|
||||
% (script, TIMEOUT, ''.encode('ascii').join(out)))
|
||||
process.stdout.close()
|
||||
process.stderr.close()
|
||||
return tester
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
# Copyright (C) 2021, Benjamin Drung <bdrung@debian.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""Run isort to check if Python import definitions are sorted."""
|
||||
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from . import get_source_files, unittest_verbosity
|
||||
|
||||
|
||||
class IsortTestCase(unittest.TestCase):
|
||||
"""
|
||||
This unittest class provides a test that runs isort to check if
|
||||
Python import definitions are sorted. The list of source files
|
||||
is provided by the get_source_files() function.
|
||||
"""
|
||||
|
||||
def test_isort(self) -> None:
|
||||
"""Test: Run isort on Python source code."""
|
||||
cmd = ["isort", "--check-only", "--diff", "-l", "99"] + get_source_files()
|
||||
if unittest_verbosity() >= 2:
|
||||
sys.stderr.write(f"Running following command:\n{' '.join(cmd)}\n")
|
||||
process = subprocess.run(cmd, capture_output=True, check=False, text=True)
|
||||
|
||||
if process.returncode != 0: # pragma: no cover
|
||||
self.fail(f"isort found unsorted Python import definitions:\n{process.stdout.strip()}")
|
|
@ -0,0 +1,61 @@
|
|||
# Copyright (C) 2023, Benjamin Drung <bdrung@ubuntu.com>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""Run mypy to check static typing of the Python code."""
|
||||
|
||||
import shutil
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from . import get_source_files, unittest_verbosity
|
||||
|
||||
|
||||
class MypyTestCase(unittest.TestCase):
|
||||
"""
|
||||
This unittest class provides a test that runs mypy to check static
|
||||
typing of the Python code. The list of source files is provided by
|
||||
the get_source_files() function.
|
||||
"""
|
||||
|
||||
@unittest.skipIf(not shutil.which("mypy"), "mypy not found")
|
||||
def test_mypy(self) -> None:
|
||||
"""Test: Run mypy on Python source code."""
|
||||
# The *-distro-info binaries do not have type hints.
|
||||
# Exlude system installed modules due to https://github.com/python/mypy/issues/14559
|
||||
sources = [
|
||||
s for s in get_source_files() if not (s.endswith("-distro-info") or s.startswith("/"))
|
||||
]
|
||||
# PEP 561 does not support distributing typing information as part of module-only
|
||||
# distributions. So suppress errors for missing type hints of installed `distro_info`.
|
||||
cmd = ["mypy", "--ignore-missing-imports", "--strict"] + sources
|
||||
if unittest_verbosity() >= 2:
|
||||
sys.stderr.write(f"Running following command:\n{' '.join(cmd)}\n")
|
||||
process = subprocess.run(cmd, capture_output=True, check=False, text=True)
|
||||
|
||||
if process.returncode != 0: # pragma: no cover
|
||||
msgs = []
|
||||
if process.stderr:
|
||||
msgs.append(
|
||||
f"mypy exited with code {process.returncode} and has"
|
||||
f" unexpected output on stderr:\n{process.stderr.rstrip()}"
|
||||
)
|
||||
if process.stdout:
|
||||
msgs.append(f"mypy found issues:\n{process.stdout.rstrip()}")
|
||||
if not msgs:
|
||||
msgs.append(
|
||||
f"mypy exited with code {process.returncode} "
|
||||
"and has no output on stdout or stderr."
|
||||
)
|
||||
self.fail("\n".join(msgs))
|
|
@ -13,7 +13,7 @@
|
|||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""test_pylint.py - Run pylint"""
|
||||
"""Run pylint."""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
@ -34,15 +34,12 @@ class PylintTestCase(unittest.TestCase):
|
|||
a config file.
|
||||
"""
|
||||
|
||||
def test_pylint(self):
|
||||
"""Test: Run pylint on Python source code"""
|
||||
|
||||
cmd = [sys.executable, "-m", "pylint", "--rcfile=" + CONFIG, "--"] + get_source_files()
|
||||
def test_pylint(self) -> None:
|
||||
"""Test: Run pylint on Python source code."""
|
||||
cmd = ["pylint", "--rcfile=" + CONFIG] + get_source_files()
|
||||
if unittest_verbosity() >= 2:
|
||||
sys.stderr.write("Running following command:\n{}\n".format(" ".join(cmd)))
|
||||
process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
close_fds=True)
|
||||
out, err = process.communicate()
|
||||
sys.stderr.write(f"Running following command:\n{' '.join(cmd)}\n")
|
||||
process = subprocess.run(cmd, capture_output=True, check=False, text=True)
|
||||
|
||||
if process.returncode != 0: # pragma: no cover
|
||||
# Strip trailing summary (introduced in pylint 1.7). This summary might look like:
|
||||
|
@ -50,19 +47,24 @@ class PylintTestCase(unittest.TestCase):
|
|||
# ------------------------------------
|
||||
# Your code has been rated at 10.00/10
|
||||
#
|
||||
out = re.sub("^(-+|Your code has been rated at .*)$", "", out.decode(),
|
||||
flags=re.MULTILINE).rstrip()
|
||||
out = re.sub(
|
||||
"^(-+|Your code has been rated at .*)$", "", process.stdout, flags=re.MULTILINE
|
||||
).rstrip()
|
||||
|
||||
# Strip logging of used config file (introduced in pylint 1.8)
|
||||
err = re.sub("^Using config file .*\n", "", err.decode()).rstrip()
|
||||
err = re.sub("^Using config file .*\n", "", process.stderr.rstrip())
|
||||
|
||||
msgs = []
|
||||
if err:
|
||||
msgs.append("pylint exited with code {} and has unexpected output on stderr:\n{}"
|
||||
.format(process.returncode, err))
|
||||
msgs.append(
|
||||
f"pylint exited with code {process.returncode} "
|
||||
f"and has unexpected output on stderr:\n{err}"
|
||||
)
|
||||
if out:
|
||||
msgs.append("pylint found issues:\n{}".format(out))
|
||||
msgs.append(f"pylint found issues:\n{out}")
|
||||
if not msgs:
|
||||
msgs.append("pylint exited with code {} and has no output on stdout or stderr."
|
||||
.format(process.returncode))
|
||||
msgs.append(
|
||||
f"pylint exited with code {process.returncode} "
|
||||
"and has no output on stdout or stderr."
|
||||
)
|
||||
self.fail("\n".join(msgs))
|
||||
|
|
|
@ -0,0 +1,58 @@
|
|||
# Copyright (C) 2022, Benjamin Drung <bdrung@debian.org>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
# AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
# PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
"""Test functions in setup.py."""
|
||||
|
||||
import unittest
|
||||
import unittest.mock
|
||||
|
||||
from setup import make_pep440_compliant
|
||||
|
||||
|
||||
class SetupTestCase(unittest.TestCase):
|
||||
"""Test functions in setup.py."""
|
||||
|
||||
def test_make_pep440_compliant_unchanged(self) -> None:
|
||||
"""Test make_pep440_compliant() with already correct version."""
|
||||
self.assertEqual(make_pep440_compliant("1.2"), "1.2")
|
||||
|
||||
def test_make_pep440_compliant_debian_backport(self) -> None:
|
||||
"""Test make_pep440_compliant() with Debian backport version."""
|
||||
self.assertEqual(make_pep440_compliant("0.21~bpo9+1"), "0.21+bpo9.1")
|
||||
|
||||
def test_make_pep440_compliant_debian_stable(self) -> None:
|
||||
"""Test make_pep440_compliant() with Debian stable update."""
|
||||
self.assertEqual(make_pep440_compliant("2.21.3+deb11u1"), "2.21.3+deb11u1")
|
||||
|
||||
def test_make_pep440_compliant_debian_stable_backport(self) -> None:
|
||||
"""Test make_pep440_compliant() with Debian stable backport."""
|
||||
self.assertEqual(make_pep440_compliant("2.21.3+deb11u1~bpo10+1"), "2.21.3+deb11u1.bpo10.1")
|
||||
|
||||
def test_make_pep440_compliant_tilde(self) -> None:
|
||||
"""Test make_pep440_compliant() with tilde in Debian version."""
|
||||
self.assertEqual(make_pep440_compliant("0.175~18.04.3"), "0.175+18.04.3")
|
||||
|
||||
def test_make_pep440_compliant_ubuntu(self) -> None:
|
||||
"""Test make_pep440_compliant() with Ubuntu version."""
|
||||
self.assertEqual(make_pep440_compliant("1.1ubuntu1"), "1.1+ubuntu1")
|
||||
|
||||
def test_make_pep440_compliant_ubuntu_backport(self) -> None:
|
||||
"""Test make_pep440_compliant() with Ubuntu backport version."""
|
||||
self.assertEqual(
|
||||
make_pep440_compliant("2.22.1ubuntu1~bpo20.04.1"), "2.22.1+ubuntu1.bpo20.04.1"
|
||||
)
|
||||
|
||||
def test_make_pep440_compliant_ubuntu_security(self) -> None:
|
||||
"""Test make_pep440_compliant() with Ubuntu security update."""
|
||||
self.assertEqual(make_pep440_compliant("2.17.12ubuntu1.1"), "2.17.12+ubuntu1.1")
|
|
@ -1,36 +1,47 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
import re
|
||||
|
||||
from setuptools import setup
|
||||
|
||||
|
||||
PACKAGES = []
|
||||
PY_MODULES = ['distro_info']
|
||||
SCRIPTS = [
|
||||
'debian-distro-info',
|
||||
'ubuntu-distro-info',
|
||||
]
|
||||
PACKAGES = ["distro_info"]
|
||||
PY_MODULES = ["distro_info"]
|
||||
SCRIPTS = ["debian-distro-info", "ubuntu-distro-info"]
|
||||
|
||||
|
||||
def get_debian_version():
|
||||
def get_debian_version() -> str:
|
||||
"""look what Debian version we have"""
|
||||
version = None
|
||||
changelog = "../debian/changelog"
|
||||
if os.path.exists(changelog):
|
||||
head = open(changelog, "rb").readline().decode("utf-8")
|
||||
match = re.compile(r".*\((.*)\).*").match(head)
|
||||
if match:
|
||||
version = match.group(1)
|
||||
return version
|
||||
changelog = pathlib.Path(__file__).parent.parent / "debian" / "changelog"
|
||||
with changelog.open("r", encoding="utf-8") as changelog_f:
|
||||
head = changelog_f.readline()
|
||||
match = re.compile(r".*\((.*)\).*").match(head)
|
||||
if not match:
|
||||
raise ValueError(f"Failed to extract Debian version from '{head}'.")
|
||||
return match.group(1)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
def make_pep440_compliant(version: str) -> str:
|
||||
"""Convert the version into a PEP440 compliant version."""
|
||||
public_version_re = re.compile(r"^([0-9][0-9.]*(?:(?:a|b|rc|.post|.dev)[0-9]+)*)\+?")
|
||||
_, public, local = public_version_re.split(version, maxsplit=1)
|
||||
if not local:
|
||||
return version
|
||||
sanitized_local = re.sub("[+~]+", ".", local).strip(".")
|
||||
pep440_version = f"{public}+{sanitized_local}"
|
||||
assert re.match("^[a-zA-Z0-9.]+$", sanitized_local), f"'{pep440_version}' not PEP440 compliant"
|
||||
return pep440_version
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
setup(
|
||||
name='distro-info',
|
||||
version=get_debian_version(),
|
||||
name="distro-info",
|
||||
version=make_pep440_compliant(get_debian_version()),
|
||||
py_modules=PY_MODULES,
|
||||
packages=PACKAGES,
|
||||
test_suite="distro_info_test",
|
||||
url="https://salsa.debian.org/debian/distro-info",
|
||||
author="Benjamin Drung",
|
||||
author_email="bdrung@debian.org",
|
||||
package_data={"distro_info": ["py.typed"]},
|
||||
)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#!/usr/bin/python
|
||||
#!/usr/bin/python3
|
||||
|
||||
# Copyright (C) 2009-2011, Benjamin Drung <bdrung@debian.org>
|
||||
#
|
||||
|
@ -23,49 +23,65 @@ import argparse
|
|||
import os
|
||||
import sys
|
||||
|
||||
from distro_info import convert_date, UbuntuDistroInfo
|
||||
from distro_info import UbuntuDistroInfo, convert_date
|
||||
|
||||
|
||||
def parse_args():
|
||||
def parse_args() -> argparse.Namespace:
|
||||
script_name = os.path.basename(sys.argv[0])
|
||||
usage = "%s [options]" % (script_name)
|
||||
epilog = "See %s(1) for more info." % (script_name)
|
||||
usage = f"{script_name} [options]"
|
||||
epilog = f"See {script_name}(1) for more info."
|
||||
parser = argparse.ArgumentParser(usage=usage, epilog=epilog)
|
||||
|
||||
parser.add_argument("--date", dest="date", default=None,
|
||||
help="date for calculating the version (default: today).")
|
||||
parser.add_argument("-a", "--all", dest="all", action="store_true",
|
||||
help="list all known versions")
|
||||
parser.add_argument("-d", "--devel", dest="devel", action="store_true",
|
||||
help="latest development version")
|
||||
parser.add_argument("--lts", dest="lts", action="store_true",
|
||||
help="latest long term support (LTS) version")
|
||||
parser.add_argument("-s", "--stable", dest="stable", action="store_true",
|
||||
help="latest stable version")
|
||||
parser.add_argument("--supported", dest="supported", action="store_true",
|
||||
help="list of all supported stable versions")
|
||||
parser.add_argument("--unsupported", dest="unsupported", action="store_true",
|
||||
help="list of all unsupported stable versions")
|
||||
parser.add_argument(
|
||||
"--date",
|
||||
dest="date",
|
||||
default=None,
|
||||
help="date for calculating the version (default: today).",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-a", "--all", dest="all", action="store_true", help="list all known versions"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-d", "--devel", dest="devel", action="store_true", help="latest development version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"-s", "--stable", dest="stable", action="store_true", help="latest stable version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--lts", dest="lts", action="store_true", help="latest long term support (LTS) version"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--supported",
|
||||
dest="supported",
|
||||
action="store_true",
|
||||
help="list of all supported versions (including development)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--unsupported",
|
||||
dest="unsupported",
|
||||
action="store_true",
|
||||
help="list of all unsupported stable versions",
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
versions = [args.all, args.devel, args.lts, args.stable,
|
||||
args.supported, args.unsupported]
|
||||
versions = [args.all, args.devel, args.lts, args.stable, args.supported, args.unsupported]
|
||||
if len([x for x in versions if x]) != 1:
|
||||
parser.error("You have to select exactly one of --all, --devel, --lts, "
|
||||
"--stable, --supported, --unsupported.")
|
||||
parser.error(
|
||||
"You have to select exactly one of --all, --devel, --lts, "
|
||||
"--stable, --supported, --unsupported."
|
||||
)
|
||||
|
||||
if args.date is not None:
|
||||
try:
|
||||
args.date = convert_date(args.date)
|
||||
except ValueError:
|
||||
parser.error("Option --date needs to be a date in ISO 8601 "
|
||||
"format.")
|
||||
parser.error("Option --date needs to be a date in ISO 8601 format.")
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
if args.all:
|
||||
for distro in UbuntuDistroInfo().all:
|
||||
|
|
|
@ -3,10 +3,10 @@ VENDOR ?= $(shell dpkg-vendor --query Vendor | tr '[:upper:]' '[:lower:]')
|
|||
|
||||
build: debian-distro-info ubuntu-distro-info
|
||||
|
||||
%-distro-info: debian-distro-info.in distro-info-util.sh
|
||||
%-distro-info: %-distro-info.in distro-info-util.sh
|
||||
sed -e '/^\. .*distro-info-util.sh\"$$/r distro-info-util.sh' $< | \
|
||||
sed -e '/^##/d;/^\. .*distro-info-util.sh\"$$/d' | \
|
||||
python -c 'import re,sys;print re.sub("(?<=\n)#BEGIN \w*#\n(.|\n)*?\n#END \w*#\n", "", re.sub("(?<=\n)#(BEGIN|END) $*#\n", "", sys.stdin.read())),' > $@
|
||||
python3 -c 'import re,sys;print(re.sub("(?<=\n)#BEGIN \w*#\n(.|\n)*?\n#END \w*#\n", "", re.sub("(?<=\n)#(BEGIN|END) $*#\n", "", sys.stdin.read())), end="")' > $@
|
||||
chmod +x $@
|
||||
|
||||
install: debian-distro-info ubuntu-distro-info
|
||||
|
|
|
@ -17,7 +17,7 @@ set -f
|
|||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
DISTRO_INFO_NAME="Debian"
|
||||
DISTRO_INFO_ARGS="--all --devel --oldstable --stable --supported
|
||||
DISTRO_INFO_ARGS="--all --devel --elts --lts --oldstable --stable --supported
|
||||
--testing --unsupported"
|
||||
DISTRO_INFO_DATA="/usr/share/distro-info/debian.csv"
|
||||
|
||||
|
@ -32,10 +32,12 @@ Options:
|
|||
--date=DATE date for calculating the version (default: today)
|
||||
-a --all list all known versions
|
||||
-d --devel latest development version
|
||||
-o --oldstable latest oldstable version
|
||||
-s --stable latest stable version
|
||||
--supported list of all supported stable versions
|
||||
-t --testing current testing version
|
||||
-s --stable latest stable version
|
||||
-o --oldstable latest oldstable version
|
||||
--supported list of all supported versions (including development)
|
||||
-l --lts list of all LTS versions
|
||||
-e --elts list of all Extended LTS versions
|
||||
--unsupported list of all unsupported stable versions
|
||||
-c --codename print the codename (default)
|
||||
-r --release print the release version
|
||||
|
@ -59,6 +61,15 @@ cb_testing() {
|
|||
store
|
||||
return 1;
|
||||
}
|
||||
cb_supported() {
|
||||
date_ge "$eol" "$CMP_DATE" && created
|
||||
}
|
||||
cb_lts() {
|
||||
date_ge "$eollts" "$CMP_DATE" && ! date_ge "$eol" "$CMP_DATE" && created
|
||||
}
|
||||
cb_elts() {
|
||||
date_ge "$eolelts" "$CMP_DATE" && ! date_ge "$eollts" "$CMP_DATE" && created
|
||||
}
|
||||
|
||||
main "$@"
|
||||
|
||||
|
|
|
@ -25,7 +25,14 @@ store() {
|
|||
s_created=$created;
|
||||
s_release=$release;
|
||||
s_eol=$eol;
|
||||
#BEGIN debian#
|
||||
s_eollts=$eollts;
|
||||
s_eolelts=$eolelts;
|
||||
#END debian#
|
||||
#BEGIN ubuntu#
|
||||
s_eols=$eols;
|
||||
s_eolesm=$eolesm;
|
||||
#END ubuntu#
|
||||
}
|
||||
restore() {
|
||||
# restore data previously stored with store
|
||||
|
@ -35,7 +42,14 @@ restore() {
|
|||
created=$s_created;
|
||||
release=$s_release;
|
||||
eol=$s_eol;
|
||||
#BEGIN debian#
|
||||
eollts=$s_eollts;
|
||||
eolelts=$s_eolelts;
|
||||
#END debian#
|
||||
#BEGIN ubuntu#
|
||||
eols=$s_eols;
|
||||
eolesm=$s_eolesm;
|
||||
#END ubuntu#
|
||||
}
|
||||
|
||||
created() {
|
||||
|
@ -60,7 +74,13 @@ devel() {
|
|||
next_is() {
|
||||
# call a function as if you were calling it for next
|
||||
local version=$n_version codename=$n_codename series=$n_series
|
||||
local created=$n_created release=$n_release eol=$n_eol eols=$n_eols
|
||||
local created=$n_created release=$n_release eol=$n_eol
|
||||
#BEGIN debian#
|
||||
local eollts=$n_eollts eolelts=$in_eolelts
|
||||
#END debian#
|
||||
#BEGIN ubuntu#
|
||||
local eols=$n_eols eolesm=$n_eolesm
|
||||
#END ubuntu#
|
||||
"$@"
|
||||
}
|
||||
|
||||
|
@ -75,9 +95,6 @@ cb_stable() {
|
|||
released && [ -n "$n_version" ] && ! next_is released && store
|
||||
return 1;
|
||||
}
|
||||
cb_supported() {
|
||||
date_ge "$eols" "$CMP_DATE" && created
|
||||
}
|
||||
cb_unsupported() {
|
||||
created && ! cb_supported
|
||||
}
|
||||
|
@ -97,20 +114,40 @@ filter_data() {
|
|||
local callback="$1" fmt="$2" found=0
|
||||
shift 2;
|
||||
IFS=","
|
||||
local version codename series created release eol eols
|
||||
local n_version n_codename n_series n_created n_release n_eol n_eols
|
||||
local version codename series created release eol
|
||||
local n_version n_codename n_series n_created n_release n_eol
|
||||
#BEGIN debian#
|
||||
local eollts n_eollts eolelts n_eolelts
|
||||
#END debian#
|
||||
#BEGIN ubuntu#
|
||||
local eols n_eols eolesm n_eolesm
|
||||
#END ubuntu#
|
||||
{
|
||||
read tmpvar # header of file
|
||||
read version codename series created release eol eols
|
||||
[ -n "$eol" ] || eol="9999-99-99"
|
||||
[ -n "$eols" ] || eols=$eol
|
||||
while read n_version n_codename n_series n_created n_release n_eol n_eols; do
|
||||
while read n_version n_codename n_series n_created n_release n_eol \
|
||||
#BEGIN debian#
|
||||
n_eollts n_eolelts
|
||||
#END debian#
|
||||
#BEGIN ubuntu#
|
||||
n_eols n_eolesm
|
||||
#END ubuntu#
|
||||
do
|
||||
[ -n "$n_eol" ] || n_eol="9999-99-99"
|
||||
#BEGIN ubuntu#
|
||||
[ -n "$n_eols" ] || n_eols=$n_eol
|
||||
#END ubuntu#
|
||||
"$callback" && found=$(($found+1)) && "$fmt"
|
||||
version=$n_version; codename=$n_codename; series=$n_series
|
||||
created=$n_created; release=$n_release; eol=$n_eol;
|
||||
eols=$n_eols
|
||||
#BEGIN debian#
|
||||
eollts=$n_eollts; eolelts=$n_eolelts;
|
||||
#END debian#
|
||||
#BEGIN ubuntu#
|
||||
eols=$n_eols; eolesm=$n_eolesm;
|
||||
#END ubuntu#
|
||||
done
|
||||
} < "$DISTRO_INFO_DATA"
|
||||
|
||||
|
@ -160,11 +197,11 @@ main() {
|
|||
-a|--all)
|
||||
[ -z "$callback" ] || { not_exactly_one; return 1; }
|
||||
callback="all";;
|
||||
--date=*)
|
||||
--date=*)
|
||||
date=${1#*=};
|
||||
[ -n "$date" ] || { date_requires_arg; return 1; }
|
||||
;;
|
||||
--date)
|
||||
--date)
|
||||
date="$2";
|
||||
[ -n "$2" ] || { date_requires_arg; return 1; }
|
||||
shift;;
|
||||
|
@ -181,11 +218,20 @@ main() {
|
|||
-r|--release) fmt="print_release";;
|
||||
-f|--fullname) fmt="print_fullname";;
|
||||
#BEGIN ubuntu#
|
||||
--lts)
|
||||
--lts)
|
||||
[ -z "$callback" ] || { not_exactly_one; return 1; }
|
||||
callback="lts";;
|
||||
--supported-esm)
|
||||
[ -z "$callback" ] || { not_exactly_one; return 1; }
|
||||
callback="supported_esm";;
|
||||
#END ubuntu#
|
||||
#BEGIN debian#
|
||||
-e|--elts)
|
||||
[ -z "$callback" ] || { not_exactly_one; return 1; }
|
||||
callback="elts";;
|
||||
-l|--lts)
|
||||
[ -z "$callback" ] || { not_exactly_one; return 1; }
|
||||
callback="lts";;
|
||||
-o|--oldstable|--old)
|
||||
[ -z "$callback" ] || { not_exactly_one; return 1; }
|
||||
callback="oldstable";;
|
||||
|
|
|
@ -17,27 +17,29 @@ set -f
|
|||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
DISTRO_INFO_NAME="Ubuntu"
|
||||
DISTRO_INFO_ARGS="--all --devel --lts --stable --supported --unsupported"
|
||||
DISTRO_INFO_ARGS="--all --devel --lts --stable --supported --supported-esm
|
||||
--unsupported"
|
||||
DISTRO_INFO_DATA="/usr/share/distro-info/ubuntu.csv"
|
||||
|
||||
. "${0%/*}/distro-info-util.sh"
|
||||
|
||||
Usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} [options]
|
||||
Usage: ubuntu-distro-info [options]
|
||||
|
||||
Options:
|
||||
-h --help show this help message and exit
|
||||
--date=DATE date for calculating the version (default: today)
|
||||
-a --all list all known versions
|
||||
-d --devel latest development version
|
||||
--lts latest long term support (LTS) version
|
||||
-s --stable latest stable version
|
||||
--supported list of all supported stable versions
|
||||
--unsupported list of all unsupported stable versions
|
||||
-c --codename print the codename (default)
|
||||
-r --release print the release version
|
||||
-f --fullname print the full name
|
||||
-h --help show this help message and exit
|
||||
--date=DATE date for calculating the version (default: today)
|
||||
-a --all list all known versions
|
||||
-d --devel latest development version
|
||||
-s --stable latest stable version
|
||||
--lts latest long term support (LTS) version
|
||||
--supported list of all supported versions (including development)
|
||||
--supported-esm list of all Ubuntu Advantage supported stable versions
|
||||
--unsupported list of all unsupported stable versions
|
||||
-c --codename print the codename (default)
|
||||
-r --release print the release version
|
||||
-f --fullname print the full name
|
||||
|
||||
See ubuntu-distro-info(1) for more info.
|
||||
EOF
|
||||
|
@ -47,6 +49,12 @@ cb_devel() {
|
|||
devel && store
|
||||
return 1
|
||||
}
|
||||
cb_supported() {
|
||||
date_ge "$eols" "$CMP_DATE" && created
|
||||
}
|
||||
cb_supported_esm() {
|
||||
date_ge "$eolesm" "$CMP_DATE" && created
|
||||
}
|
||||
cb_lts() {
|
||||
[ "${version#*LTS}" != "${version}" ] && released && store
|
||||
return 1;
|
||||
|
|
|
@ -26,6 +26,14 @@ runCommand() {
|
|||
assertEquals "return value of ${COMMAND} $param\n" $exp_retval $retval
|
||||
}
|
||||
|
||||
hasWarning() {
|
||||
local param="$1"
|
||||
local exp_stderr="$2"
|
||||
local stderrF="${SHUNIT_TMPDIR}/stderr"
|
||||
eval "${COMMAND} $param" > /dev/null 2> ${stderrF}
|
||||
assertEquals "error output of ${COMMAND} $param\n" "$exp_stderr" "$(cat ${stderrF})"
|
||||
}
|
||||
|
||||
success() {
|
||||
runCommand "$1" "$2" "" 0
|
||||
}
|
||||
|
|
|
@ -69,6 +69,14 @@ experimental"
|
|||
success "--date=2011-01-10 --supported" "$result"
|
||||
}
|
||||
|
||||
testLTS() {
|
||||
success "--date=2016-02-28 --lts" "squeeze"
|
||||
}
|
||||
|
||||
testELTS() {
|
||||
success "--date=2018-09-01 --elts" "wheezy"
|
||||
}
|
||||
|
||||
testUnsupported() {
|
||||
local result="buzz
|
||||
rex
|
||||
|
@ -160,15 +168,17 @@ Options:
|
|||
--date=DATE date for calculating the version (default: today)
|
||||
--series=SERIES series to calculate the version for
|
||||
-y[MILESTONE] additionally, display days until milestone
|
||||
--days=[MILESTONE] (created, release, eol)
|
||||
--days=[MILESTONE] (created, release, eol, eol-lts, eol-elts)
|
||||
--alias=DIST print the alias (oldstable, stable, testing, unstable)
|
||||
relative to the given distribution codename
|
||||
-a --all list all known versions
|
||||
-d --devel latest development version
|
||||
-o --oldstable latest oldstable version
|
||||
-s --stable latest stable version
|
||||
--supported list of all supported stable versions
|
||||
-t --testing current testing version
|
||||
-s --stable latest stable version
|
||||
-o --oldstable latest oldstable version
|
||||
--supported list of all supported versions (including development)
|
||||
-l --lts list of all LTS supported versions
|
||||
-e --elts list of all Extended LTS supported versions
|
||||
--unsupported list of all unsupported stable versions
|
||||
-c --codename print the codename (default)
|
||||
-f --fullname print the full name
|
||||
|
@ -180,7 +190,7 @@ See debian-distro-info(1) for more info.'
|
|||
}
|
||||
|
||||
testExactlyOne() {
|
||||
local result='debian-distro-info: You have to select exactly one of --alias, --all, --devel, --oldstable, --stable, --supported, --series, --testing, --unsupported.'
|
||||
local result='debian-distro-info: You have to select exactly one of --alias, --all, --devel, --elts, --lts, --oldstable, --stable, --supported, --series, --testing, --unsupported.'
|
||||
failure "" "$result"
|
||||
failure "-ad" "$result"
|
||||
failure "--alias foo -a" "$result"
|
||||
|
@ -189,7 +199,7 @@ testExactlyOne() {
|
|||
testUnrecognizedOption() {
|
||||
failure "--foo" "debian-distro-info: unrecognized option \`--foo'"
|
||||
failure "-x" "debian-distro-info: unrecognized option \`-x'"
|
||||
failure "--lts" "debian-distro-info: unrecognized option \`--lts'"
|
||||
failure "--supported-esm" "debian-distro-info: unrecognized option \`--supported-esm'"
|
||||
}
|
||||
|
||||
testUnrecognizedArguments() {
|
||||
|
@ -240,6 +250,11 @@ testUnknownSeries() {
|
|||
failure "--series foobar" "debian-distro-info: unknown distribution series \`foobar'"
|
||||
}
|
||||
|
||||
testSourceDateEpoch() {
|
||||
SOURCE_DATE_EPOCH=1675417275 success "--stable" "bullseye"
|
||||
SOURCE_DATE_EPOCH=badcoffee hasWarning "--stable" "debian-distro-info: Environment variable SOURCE_DATE_EPOCH='badcoffee' not a valid epoch. Ignoring."
|
||||
}
|
||||
|
||||
testDays() {
|
||||
# day after lenny released
|
||||
date=2009-02-15
|
||||
|
@ -315,6 +330,41 @@ testDays() {
|
|||
success "--testing --date=$date --days=eol -c" "etch 1045"
|
||||
success "--testing --date=$date --days=eol -f" "Debian 4.0 \"Etch\" 1045"
|
||||
success "--testing --date=$date --days=eol -r" "4.0 1045"
|
||||
|
||||
# day before wheezy was released
|
||||
date=2013-05-03
|
||||
|
||||
success "--testing --date=$date" "wheezy"
|
||||
|
||||
success "--testing --date=$date --days=created" "-817"
|
||||
success "--testing --date=$date --days=created -c" "wheezy -817"
|
||||
success "--testing --date=$date --days=created -f" "Debian 7 \"Wheezy\" -817"
|
||||
success "--testing --date=$date --days=created -r" "7 -817"
|
||||
|
||||
success "--testing --date=$date --days" "1"
|
||||
success "--testing --date=$date --days -c" "wheezy 1"
|
||||
success "--testing --date=$date --days -f" "Debian 7 \"Wheezy\" 1"
|
||||
success "--testing --date=$date --days -r" "7 1"
|
||||
|
||||
success "--testing --date=$date --days=release" "1"
|
||||
success "--testing --date=$date --days=release -c" "wheezy 1"
|
||||
success "--testing --date=$date --days=release -f" "Debian 7 \"Wheezy\" 1"
|
||||
success "--testing --date=$date --days=release -r" "7 1"
|
||||
|
||||
success "--testing --date=$date --days=eol" "1088"
|
||||
success "--testing --date=$date --days=eol -c" "wheezy 1088"
|
||||
success "--testing --date=$date --days=eol -f" "Debian 7 \"Wheezy\" 1088"
|
||||
success "--testing --date=$date --days=eol -r" "7 1088"
|
||||
|
||||
success "--testing --date=$date --days=eol-lts" "1854"
|
||||
success "--testing --date=$date --days=eol-lts -c" "wheezy 1854"
|
||||
success "--testing --date=$date --days=eol-lts -f" "Debian 7 \"Wheezy\" 1854"
|
||||
success "--testing --date=$date --days=eol-lts -r" "7 1854"
|
||||
|
||||
success "--testing --date=$date --days=eol-elts" "2615"
|
||||
success "--testing --date=$date --days=eol-elts -c" "wheezy 2615"
|
||||
success "--testing --date=$date --days=eol-elts -f" "Debian 7 \"Wheezy\" 2615"
|
||||
success "--testing --date=$date --days=eol-elts -r" "7 2615"
|
||||
}
|
||||
|
||||
. shunit2
|
||||
|
|
|
@ -117,9 +117,9 @@ testFullname() {
|
|||
success "--date=2011-01-10 --fullname --lts --days=eol" \
|
||||
'Ubuntu 10.04 LTS "Lucid Lynx" 850'
|
||||
success "--date=2011-01-10 --fullname --lts -yeol-server" \
|
||||
'Ubuntu 10.04 LTS "Lucid Lynx" 1570'
|
||||
'Ubuntu 10.04 LTS "Lucid Lynx" 1571'
|
||||
success "--date=2011-01-10 --fullname --lts --days=eol-server" \
|
||||
'Ubuntu 10.04 LTS "Lucid Lynx" 1570'
|
||||
'Ubuntu 10.04 LTS "Lucid Lynx" 1571'
|
||||
}
|
||||
|
||||
testRelease() {
|
||||
|
@ -141,9 +141,9 @@ testRelease() {
|
|||
success "--date=2011-01-10 --lts --release -yeol" \
|
||||
"10.04 LTS 850"
|
||||
success "--date=2011-01-10 --lts --release --days=eol-server" \
|
||||
"10.04 LTS 1570"
|
||||
"10.04 LTS 1571"
|
||||
success "--date=2011-01-10 --lts --release -yeol-server" \
|
||||
"10.04 LTS 1570"
|
||||
"10.04 LTS 1571"
|
||||
|
||||
success "--date=2011-01-10 -r --stable" "10.10"
|
||||
}
|
||||
|
@ -174,9 +174,9 @@ Options:
|
|||
--days=[MILESTONE] (created, release, eol, eol-server, eol-esm)
|
||||
-a --all list all known versions
|
||||
-d --devel latest development version
|
||||
--lts latest long term support (LTS) version
|
||||
-s --stable latest stable version
|
||||
--supported list of all supported stable versions
|
||||
--lts latest long term support (LTS) version
|
||||
--supported list of all supported versions (including development)
|
||||
--supported-esm list of all Ubuntu Advantage supported stable versions
|
||||
--unsupported list of all unsupported stable versions
|
||||
-c --codename print the codename (default)
|
||||
|
@ -246,6 +246,11 @@ testUnknownSeries() {
|
|||
failure "--series foobar" "ubuntu-distro-info: unknown distribution series \`foobar'"
|
||||
}
|
||||
|
||||
testSourceDateEpoch() {
|
||||
SOURCE_DATE_EPOCH=1664860020 success "--stable" "jammy"
|
||||
SOURCE_DATE_EPOCH=chocolate hasWarning "--stable" "ubuntu-distro-info: Environment variable SOURCE_DATE_EPOCH='chocolate' not a valid epoch. Ignoring."
|
||||
}
|
||||
|
||||
testDays() {
|
||||
# day after lucid released
|
||||
date=2010-04-30
|
||||
|
@ -272,10 +277,10 @@ testDays() {
|
|||
success "--date=$date --lts --days=eol -f" "Ubuntu 10.04 LTS \"Lucid Lynx\" 1105"
|
||||
success "--date=$date --lts --days=eol -r" "10.04 LTS 1105"
|
||||
|
||||
success "--date=$date --lts --days=eol-server" "1825"
|
||||
success "--date=$date --lts --days=eol-server -c" "lucid 1825"
|
||||
success "--date=$date --lts --days=eol-server -f" "Ubuntu 10.04 LTS \"Lucid Lynx\" 1825"
|
||||
success "--date=$date --lts --days=eol-server -r" "10.04 LTS 1825"
|
||||
success "--date=$date --lts --days=eol-server" "1826"
|
||||
success "--date=$date --lts --days=eol-server -c" "lucid 1826"
|
||||
success "--date=$date --lts --days=eol-server -f" "Ubuntu 10.04 LTS \"Lucid Lynx\" 1826"
|
||||
success "--date=$date --lts --days=eol-server -r" "10.04 LTS 1826"
|
||||
|
||||
# date precise released
|
||||
date=2012-04-26
|
||||
|
@ -297,15 +302,15 @@ testDays() {
|
|||
success "--date=$date --lts --days -f" "Ubuntu 12.04 LTS \"Precise Pangolin\" 0"
|
||||
success "--date=$date --lts --days -r" "12.04 LTS 0"
|
||||
|
||||
success "--date=$date --lts --days=eol" "1826"
|
||||
success "--date=$date --lts --days=eol -c" "precise 1826"
|
||||
success "--date=$date --lts --days=eol -f" "Ubuntu 12.04 LTS \"Precise Pangolin\" 1826"
|
||||
success "--date=$date --lts --days=eol -r" "12.04 LTS 1826"
|
||||
success "--date=$date --lts --days=eol" "1828"
|
||||
success "--date=$date --lts --days=eol -c" "precise 1828"
|
||||
success "--date=$date --lts --days=eol -f" "Ubuntu 12.04 LTS \"Precise Pangolin\" 1828"
|
||||
success "--date=$date --lts --days=eol -r" "12.04 LTS 1828"
|
||||
|
||||
success "--date=$date --lts --days=eol-server" "1826"
|
||||
success "--date=$date --lts --days=eol-server -c" "precise 1826"
|
||||
success "--date=$date --lts --days=eol-server -f" "Ubuntu 12.04 LTS \"Precise Pangolin\" 1826"
|
||||
success "--date=$date --lts --days=eol-server -r" "12.04 LTS 1826"
|
||||
success "--date=$date --lts --days=eol-server" "1828"
|
||||
success "--date=$date --lts --days=eol-server -c" "precise 1828"
|
||||
success "--date=$date --lts --days=eol-server -f" "Ubuntu 12.04 LTS \"Precise Pangolin\" 1828"
|
||||
success "--date=$date --lts --days=eol-server -r" "12.04 LTS 1828"
|
||||
|
||||
# day before raring was released
|
||||
date=2013-04-24
|
||||
|
|
Loading…
Reference in New Issue