comze 0.3.0 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +179 -62
- package/package.json +1 -1
package/dist/cli.mjs
CHANGED
|
@@ -7395,7 +7395,7 @@ var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
|
7395
7395
|
import { resolve } from "path";
|
|
7396
7396
|
|
|
7397
7397
|
// src/fetcher.ts
|
|
7398
|
-
var
|
|
7398
|
+
var import_semver3 = __toESM(require_semver2(), 1);
|
|
7399
7399
|
|
|
7400
7400
|
// src/types.ts
|
|
7401
7401
|
var STABILITY_ORDER = {
|
|
@@ -7555,7 +7555,6 @@ function formatNewVersion(originalConstraint, newVersion) {
|
|
|
7555
7555
|
import fs from "node:fs/promises";
|
|
7556
7556
|
import path from "node:path";
|
|
7557
7557
|
import os from "node:os";
|
|
7558
|
-
var CACHE_TTL = 30 * 60 * 1000;
|
|
7559
7558
|
function getCacheDir() {
|
|
7560
7559
|
const home = os.homedir();
|
|
7561
7560
|
const platform = os.platform();
|
|
@@ -7571,84 +7570,160 @@ function getCacheDir() {
|
|
|
7571
7570
|
}
|
|
7572
7571
|
return path.join(process.env.XDG_CACHE_HOME || path.join(home, ".cache"), "comze");
|
|
7573
7572
|
}
|
|
7574
|
-
async function
|
|
7573
|
+
async function getCacheEntry(key, expectedVersion) {
|
|
7575
7574
|
try {
|
|
7576
7575
|
const cacheDir = getCacheDir();
|
|
7577
7576
|
const filePath = path.join(cacheDir, `${key}.json`);
|
|
7578
7577
|
const content = await fs.readFile(filePath, "utf-8");
|
|
7579
7578
|
const data = JSON.parse(content);
|
|
7580
|
-
if (
|
|
7581
|
-
fs.unlink(filePath).catch(() => {});
|
|
7579
|
+
if (data.version !== expectedVersion) {
|
|
7582
7580
|
return null;
|
|
7583
7581
|
}
|
|
7584
|
-
return data
|
|
7582
|
+
return data;
|
|
7585
7583
|
} catch {
|
|
7586
7584
|
return null;
|
|
7587
7585
|
}
|
|
7588
7586
|
}
|
|
7589
|
-
async function setCache(key, value) {
|
|
7587
|
+
async function setCache(key, value, version, meta = {}) {
|
|
7590
7588
|
try {
|
|
7591
7589
|
const cacheDir = getCacheDir();
|
|
7592
7590
|
await fs.mkdir(cacheDir, { recursive: true });
|
|
7593
7591
|
const filePath = path.join(cacheDir, `${key}.json`);
|
|
7594
7592
|
const data = {
|
|
7593
|
+
version,
|
|
7595
7594
|
timestamp: Date.now(),
|
|
7596
|
-
value
|
|
7595
|
+
value,
|
|
7596
|
+
lastModified: meta.lastModified,
|
|
7597
|
+
etag: meta.etag
|
|
7597
7598
|
};
|
|
7598
7599
|
await fs.writeFile(filePath, JSON.stringify(data), "utf-8");
|
|
7599
7600
|
} catch {}
|
|
7600
7601
|
}
|
|
7602
|
+
async function touchCache(key, version) {
|
|
7603
|
+
try {
|
|
7604
|
+
const entry = await getCacheEntry(key, version);
|
|
7605
|
+
if (entry) {
|
|
7606
|
+
await setCache(key, entry.value, version, {
|
|
7607
|
+
lastModified: entry.lastModified,
|
|
7608
|
+
etag: entry.etag
|
|
7609
|
+
});
|
|
7610
|
+
}
|
|
7611
|
+
} catch {}
|
|
7612
|
+
}
|
|
7601
7613
|
|
|
7602
|
-
// src/
|
|
7603
|
-
var
|
|
7604
|
-
|
|
7605
|
-
|
|
7606
|
-
|
|
7607
|
-
|
|
7608
|
-
|
|
7609
|
-
|
|
7610
|
-
|
|
7614
|
+
// src/utils/php.ts
|
|
7615
|
+
var import_semver2 = __toESM(require_semver2(), 1);
|
|
7616
|
+
function normalizeComposerConstraint(constraint) {
|
|
7617
|
+
if (!constraint)
|
|
7618
|
+
return "*";
|
|
7619
|
+
let normalized = constraint.trim();
|
|
7620
|
+
normalized = normalized.replace(/\|\|/g, "<<<OR>>>");
|
|
7621
|
+
normalized = normalized.replace(/\|/g, "<<<OR>>>");
|
|
7622
|
+
normalized = normalized.replace(/<<<OR>>>/g, " || ");
|
|
7623
|
+
normalized = normalized.replace(/\s*\|\|\s*/g, " || ");
|
|
7624
|
+
normalized = normalized.replace(/,\s*/g, " ");
|
|
7625
|
+
normalized = normalized.replace(/@(dev|alpha|beta|rc|stable)/gi, "");
|
|
7626
|
+
if (normalized === "*" || normalized.startsWith("ext-")) {
|
|
7627
|
+
return "*";
|
|
7628
|
+
}
|
|
7629
|
+
return normalized;
|
|
7630
|
+
}
|
|
7631
|
+
function extractMinVersion(constraint) {
|
|
7632
|
+
const normalized = normalizeComposerConstraint(constraint);
|
|
7633
|
+
if (normalized === "*")
|
|
7634
|
+
return null;
|
|
7635
|
+
const orParts = normalized.split(/\s*\|\|\s*/);
|
|
7636
|
+
let minVersion = null;
|
|
7637
|
+
for (const part of orParts) {
|
|
7638
|
+
const coerced = import_semver2.default.coerce(part.trim());
|
|
7639
|
+
if (coerced) {
|
|
7640
|
+
if (!minVersion || import_semver2.default.lt(coerced.version, minVersion)) {
|
|
7641
|
+
minVersion = coerced.version;
|
|
7642
|
+
}
|
|
7643
|
+
}
|
|
7611
7644
|
}
|
|
7612
|
-
|
|
7613
|
-
|
|
7614
|
-
|
|
7615
|
-
|
|
7616
|
-
|
|
7617
|
-
|
|
7618
|
-
|
|
7619
|
-
|
|
7620
|
-
|
|
7621
|
-
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7631
|
-
|
|
7632
|
-
|
|
7633
|
-
|
|
7634
|
-
return
|
|
7635
|
-
|
|
7636
|
-
|
|
7645
|
+
return minVersion;
|
|
7646
|
+
}
|
|
7647
|
+
function extractMaxVersion(constraint) {
|
|
7648
|
+
const normalized = normalizeComposerConstraint(constraint);
|
|
7649
|
+
if (normalized === "*")
|
|
7650
|
+
return null;
|
|
7651
|
+
const upperBoundMatch = normalized.match(/<(=?)\s*(\d+(?:\.\d+)*)/);
|
|
7652
|
+
if (upperBoundMatch) {
|
|
7653
|
+
const coerced = import_semver2.default.coerce(upperBoundMatch[2]);
|
|
7654
|
+
return coerced ? coerced.version : null;
|
|
7655
|
+
}
|
|
7656
|
+
const caretMatch = normalized.match(/\^(\d+)(?:\.(\d+))?(?:\.(\d+))?/);
|
|
7657
|
+
if (caretMatch) {
|
|
7658
|
+
const major = parseInt(caretMatch[1], 10);
|
|
7659
|
+
return `${major + 1}.0.0`;
|
|
7660
|
+
}
|
|
7661
|
+
return null;
|
|
7662
|
+
}
|
|
7663
|
+
function checkPhpCompatibility(projectPhp, packagePhp) {
|
|
7664
|
+
if (!packagePhp || packagePhp === "*")
|
|
7665
|
+
return { satisfied: true };
|
|
7666
|
+
if (!projectPhp)
|
|
7667
|
+
return { satisfied: true };
|
|
7668
|
+
const projectMin = extractMinVersion(projectPhp);
|
|
7669
|
+
if (!projectMin)
|
|
7670
|
+
return { satisfied: true };
|
|
7671
|
+
const packageNorm = normalizeComposerConstraint(packagePhp);
|
|
7672
|
+
const packageParts = packageNorm.split(/\s*\|\|\s*/).filter((p) => p.trim());
|
|
7673
|
+
for (const part of packageParts) {
|
|
7674
|
+
const partMax = extractMaxVersion(part);
|
|
7675
|
+
if (partMax && import_semver2.default.gte(projectMin, partMax))
|
|
7676
|
+
continue;
|
|
7677
|
+
try {
|
|
7678
|
+
const range = import_semver2.default.validRange(part.trim());
|
|
7679
|
+
if (range && import_semver2.default.satisfies(projectMin, range))
|
|
7680
|
+
return { satisfied: true };
|
|
7681
|
+
} catch {}
|
|
7682
|
+
const partMin = extractMinVersion(part);
|
|
7683
|
+
if (partMin) {
|
|
7684
|
+
const partMajor = import_semver2.default.major(partMin);
|
|
7685
|
+
const projectMajor = import_semver2.default.major(projectMin);
|
|
7686
|
+
if (part.trim().startsWith("^")) {
|
|
7687
|
+
if (projectMajor === partMajor && import_semver2.default.gte(projectMin, partMin)) {
|
|
7688
|
+
return { satisfied: true };
|
|
7689
|
+
}
|
|
7690
|
+
} else if (import_semver2.default.gte(projectMin, partMin) && !partMax) {
|
|
7691
|
+
return { satisfied: true };
|
|
7692
|
+
}
|
|
7693
|
+
}
|
|
7637
7694
|
}
|
|
7695
|
+
return { satisfied: false, reason: `requires php ${packagePhp}` };
|
|
7638
7696
|
}
|
|
7639
|
-
|
|
7697
|
+
|
|
7698
|
+
// src/fetcher.ts
|
|
7699
|
+
var PACKAGIST_API = "https://repo.packagist.org/p2";
|
|
7700
|
+
var CACHE_VERSION = 1;
|
|
7701
|
+
async function fetchPackage(packageName, minStability = "stable", preferStable = true, currentVersion, allowMajor = true, noCache = false, projectPhp) {
|
|
7640
7702
|
const cacheKey = packageName.replace("/", "_");
|
|
7703
|
+
let cachedEntry = null;
|
|
7704
|
+
const headers = {};
|
|
7641
7705
|
if (!noCache) {
|
|
7642
|
-
|
|
7643
|
-
if (
|
|
7644
|
-
|
|
7706
|
+
cachedEntry = await getCacheEntry(cacheKey, CACHE_VERSION);
|
|
7707
|
+
if (cachedEntry?.lastModified) {
|
|
7708
|
+
headers["If-Modified-Since"] = cachedEntry.lastModified;
|
|
7709
|
+
}
|
|
7645
7710
|
}
|
|
7711
|
+
let data;
|
|
7646
7712
|
try {
|
|
7647
7713
|
const url = `${PACKAGIST_API}/${packageName}.json`;
|
|
7648
|
-
const response = await fetch(url);
|
|
7649
|
-
if (
|
|
7714
|
+
const response = await fetch(url, { headers });
|
|
7715
|
+
if (response.status === 304 && cachedEntry) {
|
|
7716
|
+
await touchCache(cacheKey, CACHE_VERSION);
|
|
7717
|
+
data = cachedEntry.value;
|
|
7718
|
+
} else if (response.ok) {
|
|
7719
|
+
data = await response.json();
|
|
7720
|
+
if (!noCache) {
|
|
7721
|
+
const lastModified = response.headers.get("Last-Modified") || undefined;
|
|
7722
|
+
await setCache(cacheKey, data, CACHE_VERSION, { lastModified });
|
|
7723
|
+
}
|
|
7724
|
+
} else {
|
|
7650
7725
|
return null;
|
|
7651
|
-
|
|
7726
|
+
}
|
|
7652
7727
|
const versions = data.packages?.[packageName] ?? [];
|
|
7653
7728
|
if (versions.length === 0)
|
|
7654
7729
|
return null;
|
|
@@ -7676,21 +7751,39 @@ async function fetchPackage(packageName, minStability = "stable", preferStable =
|
|
|
7676
7751
|
}
|
|
7677
7752
|
if (!selectedVersion)
|
|
7678
7753
|
return null;
|
|
7754
|
+
let phpIncompatible = false;
|
|
7755
|
+
let skippedVersion;
|
|
7756
|
+
if (projectPhp && selectedVersion.require?.php) {
|
|
7757
|
+
const phpCheck = checkPhpCompatibility(projectPhp, selectedVersion.require.php);
|
|
7758
|
+
if (!phpCheck.satisfied) {
|
|
7759
|
+
phpIncompatible = true;
|
|
7760
|
+
skippedVersion = selectedVersion.version;
|
|
7761
|
+
const versionsToCheck = preferStable ? eligibleVersions.filter((v) => getVersionStability(v.version) === "stable") : eligibleVersions;
|
|
7762
|
+
const compatibleVersion = versionsToCheck.find((v) => {
|
|
7763
|
+
if (!v.require?.php)
|
|
7764
|
+
return true;
|
|
7765
|
+
return checkPhpCompatibility(projectPhp, v.require.php).satisfied;
|
|
7766
|
+
});
|
|
7767
|
+
if (compatibleVersion && compatibleVersion !== selectedVersion) {
|
|
7768
|
+
selectedVersion = compatibleVersion;
|
|
7769
|
+
}
|
|
7770
|
+
}
|
|
7771
|
+
}
|
|
7679
7772
|
const phpRequirement = selectedVersion.require?.php;
|
|
7680
7773
|
let majorDetected;
|
|
7681
7774
|
if (currentVersion) {
|
|
7682
7775
|
const currentNorm = normalizeVersion(currentVersion);
|
|
7683
7776
|
const selectedNorm = normalizeVersion(selectedVersion.version);
|
|
7684
7777
|
if (currentNorm && selectedNorm) {
|
|
7685
|
-
const currentMajor =
|
|
7686
|
-
const selectedMajor =
|
|
7778
|
+
const currentMajor = import_semver3.default.major(currentNorm);
|
|
7779
|
+
const selectedMajor = import_semver3.default.major(selectedNorm);
|
|
7687
7780
|
if (selectedMajor > currentMajor) {
|
|
7688
7781
|
majorDetected = selectedVersion.version;
|
|
7689
7782
|
if (!allowMajor) {
|
|
7690
7783
|
const versionsToCheck = preferStable ? eligibleVersions.filter((v) => getVersionStability(v.version) === "stable") : eligibleVersions;
|
|
7691
7784
|
const sameMajorVersion = versionsToCheck.find((v) => {
|
|
7692
7785
|
const norm = normalizeVersion(v.version);
|
|
7693
|
-
return norm &&
|
|
7786
|
+
return norm && import_semver3.default.major(norm) === currentMajor;
|
|
7694
7787
|
});
|
|
7695
7788
|
if (sameMajorVersion) {
|
|
7696
7789
|
selectedVersion = sameMajorVersion;
|
|
@@ -7699,31 +7792,37 @@ async function fetchPackage(packageName, minStability = "stable", preferStable =
|
|
|
7699
7792
|
}
|
|
7700
7793
|
}
|
|
7701
7794
|
}
|
|
7702
|
-
const deprecatedInfo =
|
|
7795
|
+
const deprecatedInfo = {};
|
|
7796
|
+
if (typeof selectedVersion.abandoned === "string") {
|
|
7797
|
+
deprecatedInfo.deprecated = true;
|
|
7798
|
+
deprecatedInfo.replacement = selectedVersion.abandoned;
|
|
7799
|
+
} else if (selectedVersion.abandoned) {
|
|
7800
|
+
deprecatedInfo.deprecated = true;
|
|
7801
|
+
}
|
|
7703
7802
|
const result = {
|
|
7704
7803
|
latestVersion: selectedVersion.version,
|
|
7705
7804
|
releaseTime: selectedVersion.time,
|
|
7706
7805
|
phpRequirement: selectedVersion.require?.php ?? phpRequirement,
|
|
7707
7806
|
majorVersion: majorDetected,
|
|
7708
7807
|
deprecated: deprecatedInfo.deprecated,
|
|
7709
|
-
replacement: deprecatedInfo.replacement
|
|
7808
|
+
replacement: deprecatedInfo.replacement,
|
|
7809
|
+
phpIncompatible: phpIncompatible || undefined,
|
|
7810
|
+
skippedVersion,
|
|
7811
|
+
require: selectedVersion.require
|
|
7710
7812
|
};
|
|
7711
|
-
if (!noCache) {
|
|
7712
|
-
await setCache(cacheKey, result);
|
|
7713
|
-
}
|
|
7714
7813
|
return result;
|
|
7715
7814
|
} catch {
|
|
7716
7815
|
return null;
|
|
7717
7816
|
}
|
|
7718
7817
|
}
|
|
7719
|
-
async function fetchAllPackages(packages, minStability = "stable", preferStable = true, allowMajor = true, noCache = false) {
|
|
7818
|
+
async function fetchAllPackages(packages, minStability = "stable", preferStable = true, allowMajor = true, noCache = false, projectPhp) {
|
|
7720
7819
|
const results = new Map;
|
|
7721
7820
|
const entries = Object.entries(packages);
|
|
7722
7821
|
const CONCURRENCY = 5;
|
|
7723
7822
|
for (let i = 0;i < entries.length; i += CONCURRENCY) {
|
|
7724
7823
|
const batch = entries.slice(i, i + CONCURRENCY);
|
|
7725
7824
|
const promises = batch.map(async ([name, version]) => {
|
|
7726
|
-
const result = await fetchPackage(name, minStability, preferStable, version, allowMajor, noCache);
|
|
7825
|
+
const result = await fetchPackage(name, minStability, preferStable, version, allowMajor, noCache, projectPhp);
|
|
7727
7826
|
if (result)
|
|
7728
7827
|
results.set(name, result);
|
|
7729
7828
|
});
|
|
@@ -7980,6 +8079,9 @@ function renderTable(packages) {
|
|
|
7980
8079
|
if (pkg.phpRequirement) {
|
|
7981
8080
|
extra += import_picocolors.default.gray(` php ${pkg.phpRequirement}`);
|
|
7982
8081
|
}
|
|
8082
|
+
if (pkg.phpIncompatible && pkg.skippedVersion) {
|
|
8083
|
+
extra += import_picocolors.default.yellow(` ${pkg.skippedVersion} skipped (php)`);
|
|
8084
|
+
}
|
|
7983
8085
|
if (pkg.deprecated) {
|
|
7984
8086
|
extra += import_picocolors.default.red(" deprecated");
|
|
7985
8087
|
if (pkg.replacement) {
|
|
@@ -7988,6 +8090,15 @@ function renderTable(packages) {
|
|
|
7988
8090
|
}
|
|
7989
8091
|
console.log(` ${name} ${oldVer} ${arrow} ${coloredNewVer} ${diffLabel} ${age}${extra}`);
|
|
7990
8092
|
}
|
|
8093
|
+
const skippedPackages = packages.filter((p) => p.phpIncompatible && p.skippedVersion);
|
|
8094
|
+
if (skippedPackages.length > 0) {
|
|
8095
|
+
console.log(import_picocolors.default.yellow(`
|
|
8096
|
+
Some versions skipped due to PHP constraints:`));
|
|
8097
|
+
for (const pkg of skippedPackages) {
|
|
8098
|
+
console.log(` ${import_picocolors.default.bold(pkg.name)} ${pkg.skippedVersion} requires higher PHP version`);
|
|
8099
|
+
}
|
|
8100
|
+
console.log(import_picocolors.default.gray(" Update the php constraint in composer.json to use these versions."));
|
|
8101
|
+
}
|
|
7991
8102
|
console.log("");
|
|
7992
8103
|
}
|
|
7993
8104
|
function renderHeader(version) {
|
|
@@ -8028,6 +8139,9 @@ function formatPackageChoice(pkg) {
|
|
|
8028
8139
|
if (pkg.phpRequirement) {
|
|
8029
8140
|
extra += import_picocolors.default.gray(` php ${pkg.phpRequirement}`);
|
|
8030
8141
|
}
|
|
8142
|
+
if (pkg.phpIncompatible && pkg.skippedVersion) {
|
|
8143
|
+
extra += import_picocolors.default.yellow(` ${pkg.skippedVersion} skipped`);
|
|
8144
|
+
}
|
|
8031
8145
|
if (pkg.deprecated) {
|
|
8032
8146
|
extra += import_picocolors.default.red(" deprecated");
|
|
8033
8147
|
if (pkg.replacement) {
|
|
@@ -8073,7 +8187,7 @@ async function selectPackages(packages) {
|
|
|
8073
8187
|
// package.json
|
|
8074
8188
|
var package_default = {
|
|
8075
8189
|
name: "comze",
|
|
8076
|
-
version: "0.3.
|
|
8190
|
+
version: "0.3.2",
|
|
8077
8191
|
description: "A taze-like CLI for updating composer.json dependencies",
|
|
8078
8192
|
author: "qoqn",
|
|
8079
8193
|
license: "MIT",
|
|
@@ -8149,7 +8263,8 @@ async function run(options) {
|
|
|
8149
8263
|
console.log(import_picocolors2.default.gray(` Checking ${Object.keys(filteredPackages).length} packages...`));
|
|
8150
8264
|
console.log(import_picocolors2.default.gray(` Stability: ${minStability}${preferStable ? " (prefer-stable)" : ""}
|
|
8151
8265
|
`));
|
|
8152
|
-
const
|
|
8266
|
+
const projectPhp = allPackages["php"];
|
|
8267
|
+
const results = await fetchAllPackages(filteredPackages, minStability, preferStable, options.major, options.noCache, projectPhp);
|
|
8153
8268
|
const updates = [];
|
|
8154
8269
|
const deprecatedPackages = [];
|
|
8155
8270
|
for (const [name, currentVersion] of Object.entries(filteredPackages)) {
|
|
@@ -8184,7 +8299,9 @@ async function run(options) {
|
|
|
8184
8299
|
majorAvailable,
|
|
8185
8300
|
phpRequirement: result.phpRequirement,
|
|
8186
8301
|
deprecated: result.deprecated,
|
|
8187
|
-
replacement: result.replacement
|
|
8302
|
+
replacement: result.replacement,
|
|
8303
|
+
phpIncompatible: result.phpIncompatible,
|
|
8304
|
+
skippedVersion: result.skippedVersion
|
|
8188
8305
|
});
|
|
8189
8306
|
}
|
|
8190
8307
|
const order = { major: 0, minor: 1, patch: 2 };
|