Skip to content

Commit a6a83e5

Browse files
committed
feat: output latest wanted version according to semver caret range
The output of the application will now also show the latest available version, according to the image's current version semver-caret-range. This is especially helpful, if an installed image cannot be updated to the next major version but still wants to be notified about patch/minor updates. BREAKING CHANGE: Output schema of the application changed -> Column "Upgrade Type" was removed
1 parent b76f246 commit a6a83e5

File tree

3 files changed

+48
-25
lines changed

3 files changed

+48
-25
lines changed

README.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# dc-outdated
22

3-
_dc-outdated_ (docker-compose-outdated) is a command line utiltiy that allows to easily check for outdated docker images in your docker-compose.yml file (just like _outdated_ command in _npm_ or _yarn_).
3+
Command line utiliy for checking outdated docker-compose images.
44

5-
Therefore it fetches for each image definition in your docker-compose.yml file, the latest available tag (according to the _semver_ versioning schema -> tags that do not match the semver versioning schema will be ignored) from the according docker registry. If the version (tag) of the image definition in the _docker-compose.yml_ file.
5+
_dc-outdated_ (docker-compose-outdated) is a command line utiltiy that allows to easily check for outdated docker images in your docker-compose.yml file (just like _outdated_ command in _npm_ or _yarn_). Therefore it iterates over each image definition in your docker-compose.yml file, and fetches the latest available tag-name form the appropriate docker registry (according to the _semver_ versioning schema). Tags that do not match the semver versioning schema will be ignored.
66

77
## Prerequisites
88

9-
If you are using images from a private registry it is neccessary to login to that registry (_docker login_ command) before executing this application. This is required, since _dc-outdated_ reads login-credentials from the user's docker config file by default. By default, this application searches for a _docker-compose.yml_ file in the current working directory (same behavior as docker-compose utility). Hence, the directory in which the application is executed, must contain a valid **docker-compose.yml** file.
9+
If you are using images from a private registry it is neccessary to login to that registry (_docker login_ command) before executing this application. This is required, since _dc-outdated_ reads login-credentials from the user's docker config file by default.
10+
By default, this application searches for a _docker-compose.yml_ file in the current working directory (same behavior as docker-compose utility). Hence, the directory in which the application is executed, must contain a valid **docker-compose.yml** file.
1011
In order to make this tool work correctly it is neccessary that all images in the _docker-compose.yml_ file are specified with a semver compliant tag. Otherwise execution will fail.
1112

1213

@@ -20,14 +21,14 @@ cd /path/to/your/project
2021
dc-outdated
2122
```
2223

23-
If the compose file contains outdated docker images, the programm will list the outdated image names as well as the current and latest version of the image:
24+
If the compose file contains outdated docker images, the programm will list the outdated image names. Besides the image name, the application will also output the **current** image version (as specified in the _docker-compose.yml_ file), the next **wanted** version (max possible version according to the image's current version caret range) and the **latest** version of the image.
2425

2526
```
26-
Image Upgrade Type Current Version Latest Version
27-
-------------------- ------------ --------------- --------------
28-
library/rabbitmq minor 3.6.16 3.7.7
29-
library/mongo minor 3.4.16 3.6.6
30-
library/influxdb major 0.13.0 1.5.4
27+
Image Current Wanted[^] Latest
28+
-------------------- --------- ----------- ------------
29+
library/rabbitmq 3.6.16 3.7.11 3.8.0-beta.2
30+
library/mongo 3.4.16 3.7.9 4.1.7
31+
library/influxdb 0.13.0 1.7.3 1.7.3
3132
```
3233

3334
For advanced usage, command line flags can be used to change the default behavoir of the application:
@@ -45,4 +46,4 @@ However, for a fully detailed description of all flags that can be used, see the
4546
## TODOs
4647

4748
* For now only docker compose files of version 2.x were tested. For the future docker-compose version 3 should be supported too
48-
* At this moment checking for outdated images on against the official docker registry is not fully working. Hence, only images from a self-hosted docker registry (v2) can be checked reliable. This will be changed in the future so that all kind of docker registries are supported. For now you will have to login to _registry-1.docker.io_ in order to verfy images from offical docker registry.
49+
* At this moment checking for outdated images against the official docker registry is not fully working. Hence, only images from a self-hosted docker registry (v2) can be checked reliable. This will be changed in the future so that all kind of docker registries are supported. For now you will have to login to _registry-1.docker.io_ in order to verfy images from offical docker registry.

src/lib/docker-utils.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,26 @@ export async function listRepositories(registryHost: string, credentialsStore: C
173173
}
174174

175175
export async function getLatestImageVersion(credentialsStore: CredentialsStore, dockerImage: DockerImage): Promise<string> {
176-
const tags = await listTags(credentialsStore, dockerImage);
176+
const {latest} = await getImageUpdateTags(credentialsStore, dockerImage);
177+
return latest;
178+
}
179+
180+
export async function getImageUpdateTags(credentialsStore: CredentialsStore, dockerImage: DockerImage): Promise<{wanted: string, latest: string}> {
181+
let wanted;
177182
let latest;
178-
if (tags) {
183+
const tags = await listTags(credentialsStore, dockerImage);
184+
if(tags) {
179185
const validTags = tags.filter(semver.valid);
180186
validTags.sort(semver.compare);
181187
latest = _.last(validTags);
188+
189+
if(dockerImage.tag && semver.valid(dockerImage.tag)) {
190+
wanted = semver.maxSatisfying(validTags, `^${dockerImage.tag}`);
191+
}
182192
}
183-
return latest;
193+
194+
195+
return {wanted, latest}
184196
}
185197

186198
export async function readDockerConfig(dockerConfigPath: string): Promise<any> {

src/lib/index.ts

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,17 @@
11
import * as cliProgress from 'cli-progress';
22
import * as EasyTable from 'easy-table';
33
import * as semver from 'semver';
4-
import { getComposeImages } from './compose-utils';
5-
import { Credentials, CredentialsStore, DEFAULT_REGISTRY_HOST, DockerImage, getLatestImageVersion, listRepositories, readDockerConfig } from './docker-utils';
4+
import {getComposeImages} from './compose-utils';
5+
import {
6+
Credentials,
7+
CredentialsStore,
8+
DEFAULT_REGISTRY_HOST,
9+
DockerImage,
10+
getImageUpdateTags,
11+
getLatestImageVersion,
12+
listRepositories,
13+
readDockerConfig
14+
} from './docker-utils';
615

716

817

@@ -49,7 +58,7 @@ export interface Options {
4958

5059
export interface OutdatedImage {
5160
image: DockerImage;
52-
versionDiff: string;
61+
wantedVersion: string;
5362
latestVersion: string;
5463
}
5564

@@ -88,14 +97,15 @@ export async function listOutdated(options: Options): Promise<OutdatedImage[]> {
8897

8998
try {
9099
for (const image of filteredImages) {
91-
const latestVersion = await getLatestImageVersion(credentials, image);
100+
const {latest, wanted} = await getImageUpdateTags(credentials, image);
92101

93-
const versionDiff = semver.diff(image.tag, latestVersion);
94-
if (versionDiff) {
102+
const wantedDiff = semver.diff(image.tag, wanted);
103+
const latestDiff = semver.diff(image.tag, latest);
104+
if (wantedDiff || latestDiff) {
95105
outdatedImages.push({
96106
image,
97-
versionDiff,
98-
latestVersion
107+
wantedVersion: wanted,
108+
latestVersion: latest
99109
});
100110
}
101111
progressBar.increment(1);
@@ -108,11 +118,11 @@ export async function listOutdated(options: Options): Promise<OutdatedImage[]> {
108118

109119
const table = new EasyTable();
110120

111-
outdatedImages.forEach(({image, versionDiff, latestVersion}) => {
121+
outdatedImages.forEach(({image, wantedVersion, latestVersion}) => {
112122
table.cell('Image', image.name);
113-
table.cell('Upgrade Type', versionDiff);
114-
table.cell('Current Version', image.tag);
115-
table.cell('Latest Version', latestVersion);
123+
table.cell('Current', image.tag);
124+
table.cell('Wanted[^]', wantedVersion);
125+
table.cell('Latest', latestVersion);
116126
table.newRow();
117127
});
118128

0 commit comments

Comments
 (0)