在 Node.js 中对混合格式版本标签进行排序

问题描述 投票:0回答:1

我正在尝试对标签列表进行排序,以找到最高的标签编号。这些标签来自 Dockerhub 等第三方来源,并且采用混合格式(并非全部 semver),即

const tagList = ['0.0.1', '0.0.2', '0.0.3-alpha1', '1.10-alpine3', '1.9.2']

我一直在尝试使用 compare-versions 库,但它在非语义版本上失败了。

我之前使用过 python 库来对标签进行排序,如下所示:

from packaging.version import LegacyVersion
 
tag_list = ['0.0.1', '0.0.2', '0.0.3-alpha1', '1.10-alpine3', '1.9.2']

sorted_tags = sorted(tag_list, key=LegacyVersion)

nodejs 是否有任何等效的包,或者如果没有的话,有一种对这些标签进行排序的方法吗?

到目前为止,我只能找到比较版本,但这还不够。我尝试了以下方法:

import { compareVersions } from 'compare-versions';

const versions = ['0.0.1', '0.0.2', '0.0.3-alpha1', '1.10-alpine3', '1.9.2'];
let latest;
try {
  latest = versions.sort(compareVersions).pop();
} catch {
  latest = versions.sort((a,b)=>a-b).pop();
};

console.log(latest);

预期:

1.10-alpine3

实际产量:

1.9.2

当我删除 try/catch 并强制它使用

compareVersions
排序函数时,我收到以下错误:

/Users/banbone/project/node_modules/compare-versions/lib/umd/index.js:14
            throw new Error(`Invalid argument not valid semver ('${version}' received)`);
                  ^

Error: Invalid argument not valid semver ('1.10-alpine3' received)
    at validateAndParse (/Users/banbone/project/node_modules/compare-versions/lib/umd/index.js:14:19)
    at compareVersions (/Users/banbone/project/node_modules/compare-versions/lib/umd/index.js:53:20)
    at Array.sort (<anonymous>)
    at file:///Users/banbone/project/test.js:5:19
    at ModuleJob.run (node:internal/modules/esm/module_job:218:25)
    at async ModuleLoader.import (node:internal/modules/esm/loader:329:24)
    at async loadESM (node:internal/process/esm_loader:28:7)
    at async handleMainPromise (node:internal/modules/run_main:113:12)

Node.js v21.2.0
javascript node.js sorting semantic-versioning
1个回答
0
投票

像 1.10-alpine3 这样的版本违反了语义版本控制,它必须具有三个数字和一个可选标签。

正常版本号必须采用 X.Y.Z 形式,其中 X、Y 和 Z 是 非负整数,并且不得包含前导零。 X 是 主要版本,Y 是次要版本,Z 是补丁版本。 每个元素必须在数字上增加。例如:1.9.0 -> 1.10.0 -> 1.11.0.

预发布和构建元数据的附加标签可用作 MAJOR.MINOR.PATCH 格式的扩展。

在执行比较之前,您可以使用semver的强制函数将版本解析为有效的语义版本。

const semver = require("semver");
const versions = ["0.0.1", "0.0.2", "0.0.3-alpha1", "1.10-alpine3", "1.9.2"];
const latest = versions
  .map((x) => ({ origin: x, coerced: semver.coerce(x).toString() }))
  .sort((x, y) => (semver.gt(x.coerced, y.coerced) ? 1 : -1))
  .map((x) => x.origin);
console.log(latest);
//[ '0.0.1', '0.0.2', '0.0.3-alpha1', '1.9.2', '1.10-alpine3' ]
© www.soinside.com 2019 - 2024. All rights reserved.