comze 0.1.0 → 0.3.0
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/README.md +20 -19
- package/bin/comze.mjs +1 -1
- package/dist/cli.mjs +320 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ A [taze](https://github.com/antfu/taze)-like CLI for updating `composer.json` de
|
|
|
10
10
|
- 🎯 Respects `minimum-stability` and `prefer-stable`
|
|
11
11
|
- 🚫 Major updates hidden by default
|
|
12
12
|
- ✍️ Interactive selection mode
|
|
13
|
+
- ⚠️ Detects deprecated packages
|
|
13
14
|
|
|
14
15
|
## Installation
|
|
15
16
|
|
|
@@ -50,16 +51,16 @@ comze --exclude vendor/package
|
|
|
50
51
|
|
|
51
52
|
## Options
|
|
52
53
|
|
|
53
|
-
| Flag
|
|
54
|
-
|
|
55
|
-
| `-w, --write`
|
|
56
|
-
| `-i, --install`
|
|
57
|
-
| `-I, --interactive` | Select updates manually
|
|
58
|
-
| `--major`
|
|
59
|
-
| `--minor`
|
|
60
|
-
| `--patch`
|
|
61
|
-
| `--exclude <pkgs>`
|
|
62
|
-
| `--dry-run`
|
|
54
|
+
| Flag | Description |
|
|
55
|
+
| ------------------- | --------------------------------------- |
|
|
56
|
+
| `-w, --write` | Write changes to `composer.json` |
|
|
57
|
+
| `-i, --install` | Write changes and run `composer update` |
|
|
58
|
+
| `-I, --interactive` | Select updates manually |
|
|
59
|
+
| `--major` | Include major updates (default: false) |
|
|
60
|
+
| `--minor` | Include minor updates (default: true) |
|
|
61
|
+
| `--patch` | Include patch updates (default: true) |
|
|
62
|
+
| `--exclude <pkgs>` | Exclude packages (comma-separated) |
|
|
63
|
+
| `--dry-run` | Preview changes without writing |
|
|
63
64
|
|
|
64
65
|
## Composer Stability
|
|
65
66
|
|
|
@@ -76,15 +77,15 @@ comze reads `minimum-stability` and `prefer-stable` from your `composer.json`:
|
|
|
76
77
|
|
|
77
78
|
All Composer version constraints are supported:
|
|
78
79
|
|
|
79
|
-
| Type
|
|
80
|
-
|
|
81
|
-
| Exact
|
|
82
|
-
| Caret
|
|
83
|
-
| Tilde
|
|
84
|
-
| Wildcard
|
|
85
|
-
| Range
|
|
86
|
-
| Hyphenated | `1.0 - 2.0`
|
|
87
|
-
| Dev
|
|
80
|
+
| Type | Example |
|
|
81
|
+
| ---------- | --------------------- |
|
|
82
|
+
| Exact | `1.0.2` |
|
|
83
|
+
| Caret | `^1.2.3` |
|
|
84
|
+
| Tilde | `~1.2` |
|
|
85
|
+
| Wildcard | `1.0.*` |
|
|
86
|
+
| Range | `>=1.0 <2.0` |
|
|
87
|
+
| Hyphenated | `1.0 - 2.0` |
|
|
88
|
+
| Dev | `dev-main`, `1.x-dev` |
|
|
88
89
|
|
|
89
90
|
## Development
|
|
90
91
|
|
package/bin/comze.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import
|
|
2
|
+
import "../dist/cli.mjs";
|
package/dist/cli.mjs
CHANGED
|
@@ -7394,6 +7394,9 @@ var dist_default = cac;
|
|
|
7394
7394
|
var import_picocolors2 = __toESM(require_picocolors(), 1);
|
|
7395
7395
|
import { resolve } from "path";
|
|
7396
7396
|
|
|
7397
|
+
// src/fetcher.ts
|
|
7398
|
+
var import_semver2 = __toESM(require_semver2(), 1);
|
|
7399
|
+
|
|
7397
7400
|
// src/types.ts
|
|
7398
7401
|
var STABILITY_ORDER = {
|
|
7399
7402
|
dev: 0,
|
|
@@ -7419,11 +7422,23 @@ function parseConstraint(constraint) {
|
|
|
7419
7422
|
}
|
|
7420
7423
|
if (original.startsWith("^")) {
|
|
7421
7424
|
const version = original.slice(1);
|
|
7422
|
-
return {
|
|
7425
|
+
return {
|
|
7426
|
+
type: "caret",
|
|
7427
|
+
prefix: "^",
|
|
7428
|
+
baseVersion: normalizeVersionString(version),
|
|
7429
|
+
original,
|
|
7430
|
+
isDev: hasDevSuffix(version)
|
|
7431
|
+
};
|
|
7423
7432
|
}
|
|
7424
7433
|
if (original.startsWith("~")) {
|
|
7425
7434
|
const version = original.slice(1);
|
|
7426
|
-
return {
|
|
7435
|
+
return {
|
|
7436
|
+
type: "tilde",
|
|
7437
|
+
prefix: "~",
|
|
7438
|
+
baseVersion: normalizeVersionString(version),
|
|
7439
|
+
original,
|
|
7440
|
+
isDev: hasDevSuffix(version)
|
|
7441
|
+
};
|
|
7427
7442
|
}
|
|
7428
7443
|
if (original.includes("*")) {
|
|
7429
7444
|
const basePart = (original.split("*")[0] ?? "").replace(/\.$/, "");
|
|
@@ -7431,16 +7446,34 @@ function parseConstraint(constraint) {
|
|
|
7431
7446
|
}
|
|
7432
7447
|
if (original.includes(" - ")) {
|
|
7433
7448
|
const startVersion = (original.split(" - ")[0] ?? "").trim();
|
|
7434
|
-
return {
|
|
7449
|
+
return {
|
|
7450
|
+
type: "hyphen",
|
|
7451
|
+
prefix: "",
|
|
7452
|
+
baseVersion: normalizeVersionString(startVersion),
|
|
7453
|
+
original,
|
|
7454
|
+
isDev: false
|
|
7455
|
+
};
|
|
7435
7456
|
}
|
|
7436
7457
|
const rangeMatch = original.match(/^([><!=]+)/);
|
|
7437
7458
|
if (rangeMatch) {
|
|
7438
7459
|
const versionMatch = original.match(/([><!=]+)\s*(\d+(?:\.\d+)*(?:-[\w.]+)?)/);
|
|
7439
7460
|
const version = versionMatch?.[2] ?? original.replace(/[><!=]+/g, "");
|
|
7440
7461
|
const prefix = rangeMatch[1] ?? ">=";
|
|
7441
|
-
return {
|
|
7462
|
+
return {
|
|
7463
|
+
type: "range",
|
|
7464
|
+
prefix,
|
|
7465
|
+
baseVersion: normalizeVersionString(version),
|
|
7466
|
+
original,
|
|
7467
|
+
isDev: hasDevSuffix(version)
|
|
7468
|
+
};
|
|
7442
7469
|
}
|
|
7443
|
-
return {
|
|
7470
|
+
return {
|
|
7471
|
+
type: "exact",
|
|
7472
|
+
prefix: "",
|
|
7473
|
+
baseVersion: normalizeVersionString(original),
|
|
7474
|
+
original,
|
|
7475
|
+
isDev: hasDevSuffix(original)
|
|
7476
|
+
};
|
|
7444
7477
|
}
|
|
7445
7478
|
function hasDevSuffix(version) {
|
|
7446
7479
|
const lower = version.toLowerCase();
|
|
@@ -7518,9 +7551,98 @@ function formatNewVersion(originalConstraint, newVersion) {
|
|
|
7518
7551
|
return `${parsed.prefix}${cleaned}`;
|
|
7519
7552
|
}
|
|
7520
7553
|
|
|
7554
|
+
// src/cache.ts
|
|
7555
|
+
import fs from "node:fs/promises";
|
|
7556
|
+
import path from "node:path";
|
|
7557
|
+
import os from "node:os";
|
|
7558
|
+
var CACHE_TTL = 30 * 60 * 1000;
|
|
7559
|
+
function getCacheDir() {
|
|
7560
|
+
const home = os.homedir();
|
|
7561
|
+
const platform = os.platform();
|
|
7562
|
+
const overrideDir = process.env.COMZE_CACHE_DIR?.trim();
|
|
7563
|
+
if (overrideDir) {
|
|
7564
|
+
return overrideDir;
|
|
7565
|
+
}
|
|
7566
|
+
if (platform === "win32") {
|
|
7567
|
+
return path.join(process.env.LOCALAPPDATA || path.join(home, "AppData", "Local"), "comze", "Cache");
|
|
7568
|
+
}
|
|
7569
|
+
if (platform === "darwin") {
|
|
7570
|
+
return path.join(home, "Library", "Caches", "comze");
|
|
7571
|
+
}
|
|
7572
|
+
return path.join(process.env.XDG_CACHE_HOME || path.join(home, ".cache"), "comze");
|
|
7573
|
+
}
|
|
7574
|
+
async function getCache(key) {
|
|
7575
|
+
try {
|
|
7576
|
+
const cacheDir = getCacheDir();
|
|
7577
|
+
const filePath = path.join(cacheDir, `${key}.json`);
|
|
7578
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
7579
|
+
const data = JSON.parse(content);
|
|
7580
|
+
if (Date.now() - data.timestamp > CACHE_TTL) {
|
|
7581
|
+
fs.unlink(filePath).catch(() => {});
|
|
7582
|
+
return null;
|
|
7583
|
+
}
|
|
7584
|
+
return data.value;
|
|
7585
|
+
} catch {
|
|
7586
|
+
return null;
|
|
7587
|
+
}
|
|
7588
|
+
}
|
|
7589
|
+
async function setCache(key, value) {
|
|
7590
|
+
try {
|
|
7591
|
+
const cacheDir = getCacheDir();
|
|
7592
|
+
await fs.mkdir(cacheDir, { recursive: true });
|
|
7593
|
+
const filePath = path.join(cacheDir, `${key}.json`);
|
|
7594
|
+
const data = {
|
|
7595
|
+
timestamp: Date.now(),
|
|
7596
|
+
value
|
|
7597
|
+
};
|
|
7598
|
+
await fs.writeFile(filePath, JSON.stringify(data), "utf-8");
|
|
7599
|
+
} catch {}
|
|
7600
|
+
}
|
|
7601
|
+
|
|
7521
7602
|
// src/fetcher.ts
|
|
7522
7603
|
var PACKAGIST_API = "https://repo.packagist.org/p2";
|
|
7523
|
-
|
|
7604
|
+
var PACKAGIST_PACKAGE_API = "https://packagist.org/packages";
|
|
7605
|
+
async function fetchDeprecatedInfo(packageName, noCache = false) {
|
|
7606
|
+
const cacheKey = `${packageName.replace("/", "_")}_deprecated`;
|
|
7607
|
+
if (!noCache) {
|
|
7608
|
+
const cached = await getCache(cacheKey);
|
|
7609
|
+
if (cached)
|
|
7610
|
+
return cached;
|
|
7611
|
+
}
|
|
7612
|
+
try {
|
|
7613
|
+
const url = `${PACKAGIST_PACKAGE_API}/${packageName}.json`;
|
|
7614
|
+
const response = await fetch(url);
|
|
7615
|
+
if (!response.ok)
|
|
7616
|
+
return {};
|
|
7617
|
+
const data = await response.json();
|
|
7618
|
+
const abandoned = data.package?.abandoned;
|
|
7619
|
+
if (!abandoned) {
|
|
7620
|
+
const result2 = {};
|
|
7621
|
+
if (!noCache)
|
|
7622
|
+
await setCache(cacheKey, result2);
|
|
7623
|
+
return result2;
|
|
7624
|
+
}
|
|
7625
|
+
if (typeof abandoned === "string") {
|
|
7626
|
+
const result2 = { deprecated: true, replacement: abandoned };
|
|
7627
|
+
if (!noCache)
|
|
7628
|
+
await setCache(cacheKey, result2);
|
|
7629
|
+
return result2;
|
|
7630
|
+
}
|
|
7631
|
+
const result = { deprecated: true };
|
|
7632
|
+
if (!noCache)
|
|
7633
|
+
await setCache(cacheKey, result);
|
|
7634
|
+
return result;
|
|
7635
|
+
} catch {
|
|
7636
|
+
return {};
|
|
7637
|
+
}
|
|
7638
|
+
}
|
|
7639
|
+
async function fetchPackage(packageName, minStability = "stable", preferStable = true, currentVersion, allowMajor = true, noCache = false) {
|
|
7640
|
+
const cacheKey = packageName.replace("/", "_");
|
|
7641
|
+
if (!noCache) {
|
|
7642
|
+
const cached = await getCache(cacheKey);
|
|
7643
|
+
if (cached)
|
|
7644
|
+
return cached;
|
|
7645
|
+
}
|
|
7524
7646
|
try {
|
|
7525
7647
|
const url = `${PACKAGIST_API}/${packageName}.json`;
|
|
7526
7648
|
const response = await fetch(url);
|
|
@@ -7542,31 +7664,66 @@ async function fetchPackage(packageName, minStability = "stable", preferStable =
|
|
|
7542
7664
|
return null;
|
|
7543
7665
|
return { latestVersion: first.version, releaseTime: first.time };
|
|
7544
7666
|
}
|
|
7667
|
+
let selectedVersion = null;
|
|
7545
7668
|
if (preferStable) {
|
|
7546
7669
|
const stableVersions = eligibleVersions.filter((v) => getVersionStability(v.version) === "stable");
|
|
7547
7670
|
if (stableVersions.length > 0) {
|
|
7548
|
-
|
|
7549
|
-
if (!latest2)
|
|
7550
|
-
return null;
|
|
7551
|
-
return { latestVersion: latest2.version, releaseTime: latest2.time };
|
|
7671
|
+
selectedVersion = stableVersions[0] ?? null;
|
|
7552
7672
|
}
|
|
7553
7673
|
}
|
|
7554
|
-
|
|
7555
|
-
|
|
7674
|
+
if (!selectedVersion) {
|
|
7675
|
+
selectedVersion = eligibleVersions[0] ?? null;
|
|
7676
|
+
}
|
|
7677
|
+
if (!selectedVersion)
|
|
7556
7678
|
return null;
|
|
7557
|
-
|
|
7679
|
+
const phpRequirement = selectedVersion.require?.php;
|
|
7680
|
+
let majorDetected;
|
|
7681
|
+
if (currentVersion) {
|
|
7682
|
+
const currentNorm = normalizeVersion(currentVersion);
|
|
7683
|
+
const selectedNorm = normalizeVersion(selectedVersion.version);
|
|
7684
|
+
if (currentNorm && selectedNorm) {
|
|
7685
|
+
const currentMajor = import_semver2.default.major(currentNorm);
|
|
7686
|
+
const selectedMajor = import_semver2.default.major(selectedNorm);
|
|
7687
|
+
if (selectedMajor > currentMajor) {
|
|
7688
|
+
majorDetected = selectedVersion.version;
|
|
7689
|
+
if (!allowMajor) {
|
|
7690
|
+
const versionsToCheck = preferStable ? eligibleVersions.filter((v) => getVersionStability(v.version) === "stable") : eligibleVersions;
|
|
7691
|
+
const sameMajorVersion = versionsToCheck.find((v) => {
|
|
7692
|
+
const norm = normalizeVersion(v.version);
|
|
7693
|
+
return norm && import_semver2.default.major(norm) === currentMajor;
|
|
7694
|
+
});
|
|
7695
|
+
if (sameMajorVersion) {
|
|
7696
|
+
selectedVersion = sameMajorVersion;
|
|
7697
|
+
}
|
|
7698
|
+
}
|
|
7699
|
+
}
|
|
7700
|
+
}
|
|
7701
|
+
}
|
|
7702
|
+
const deprecatedInfo = await fetchDeprecatedInfo(packageName, noCache);
|
|
7703
|
+
const result = {
|
|
7704
|
+
latestVersion: selectedVersion.version,
|
|
7705
|
+
releaseTime: selectedVersion.time,
|
|
7706
|
+
phpRequirement: selectedVersion.require?.php ?? phpRequirement,
|
|
7707
|
+
majorVersion: majorDetected,
|
|
7708
|
+
deprecated: deprecatedInfo.deprecated,
|
|
7709
|
+
replacement: deprecatedInfo.replacement
|
|
7710
|
+
};
|
|
7711
|
+
if (!noCache) {
|
|
7712
|
+
await setCache(cacheKey, result);
|
|
7713
|
+
}
|
|
7714
|
+
return result;
|
|
7558
7715
|
} catch {
|
|
7559
7716
|
return null;
|
|
7560
7717
|
}
|
|
7561
7718
|
}
|
|
7562
|
-
async function fetchAllPackages(packages, minStability = "stable", preferStable = true) {
|
|
7719
|
+
async function fetchAllPackages(packages, minStability = "stable", preferStable = true, allowMajor = true, noCache = false) {
|
|
7563
7720
|
const results = new Map;
|
|
7564
7721
|
const entries = Object.entries(packages);
|
|
7565
7722
|
const CONCURRENCY = 5;
|
|
7566
7723
|
for (let i = 0;i < entries.length; i += CONCURRENCY) {
|
|
7567
7724
|
const batch = entries.slice(i, i + CONCURRENCY);
|
|
7568
|
-
const promises = batch.map(async ([name]) => {
|
|
7569
|
-
const result = await fetchPackage(name, minStability, preferStable);
|
|
7725
|
+
const promises = batch.map(async ([name, version]) => {
|
|
7726
|
+
const result = await fetchPackage(name, minStability, preferStable, version, allowMajor, noCache);
|
|
7570
7727
|
if (result)
|
|
7571
7728
|
results.set(name, result);
|
|
7572
7729
|
});
|
|
@@ -7681,11 +7838,11 @@ function detectIndent(string) {
|
|
|
7681
7838
|
}
|
|
7682
7839
|
|
|
7683
7840
|
// src/writer.ts
|
|
7684
|
-
async function readComposerJson(
|
|
7685
|
-
if (!existsSync(
|
|
7841
|
+
async function readComposerJson(path2) {
|
|
7842
|
+
if (!existsSync(path2))
|
|
7686
7843
|
return null;
|
|
7687
7844
|
try {
|
|
7688
|
-
const raw = await readFile(
|
|
7845
|
+
const raw = await readFile(path2, "utf-8");
|
|
7689
7846
|
const indent = detectIndent(raw).indent || " ";
|
|
7690
7847
|
const content = JSON.parse(raw);
|
|
7691
7848
|
return { content, raw, indent };
|
|
@@ -7693,8 +7850,8 @@ async function readComposerJson(path) {
|
|
|
7693
7850
|
return null;
|
|
7694
7851
|
}
|
|
7695
7852
|
}
|
|
7696
|
-
async function writeComposerJson(
|
|
7697
|
-
const result = await readComposerJson(
|
|
7853
|
+
async function writeComposerJson(path2, updates, dryRun = false) {
|
|
7854
|
+
const result = await readComposerJson(path2);
|
|
7698
7855
|
if (!result)
|
|
7699
7856
|
return false;
|
|
7700
7857
|
const { content, indent } = result;
|
|
@@ -7721,7 +7878,7 @@ async function writeComposerJson(path, updates, dryRun = false) {
|
|
|
7721
7878
|
try {
|
|
7722
7879
|
const newContent = JSON.stringify(content, null, indent) + `
|
|
7723
7880
|
`;
|
|
7724
|
-
await writeFile(
|
|
7881
|
+
await writeFile(path2, newContent, "utf-8");
|
|
7725
7882
|
return true;
|
|
7726
7883
|
} catch {
|
|
7727
7884
|
return false;
|
|
@@ -7764,9 +7921,25 @@ function formatAge(isoDate) {
|
|
|
7764
7921
|
}
|
|
7765
7922
|
return "now";
|
|
7766
7923
|
}
|
|
7924
|
+
function getAgeMonths(isoDate) {
|
|
7925
|
+
const date = new Date(isoDate);
|
|
7926
|
+
const now = new Date;
|
|
7927
|
+
const diffMs = now.getTime() - date.getTime();
|
|
7928
|
+
const msPerMonth = 30 * 24 * 60 * 60 * 1000;
|
|
7929
|
+
return Math.floor(diffMs / msPerMonth);
|
|
7930
|
+
}
|
|
7767
7931
|
|
|
7768
7932
|
// src/ui/render.ts
|
|
7769
7933
|
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
7934
|
+
function colorAge(age, ageMonths) {
|
|
7935
|
+
if (ageMonths < 3) {
|
|
7936
|
+
return import_picocolors.default.green(age.padStart(6));
|
|
7937
|
+
} else if (ageMonths < 12) {
|
|
7938
|
+
return import_picocolors.default.yellow(age.padStart(6));
|
|
7939
|
+
} else {
|
|
7940
|
+
return import_picocolors.default.red(age.padStart(6));
|
|
7941
|
+
}
|
|
7942
|
+
}
|
|
7770
7943
|
function renderTable(packages) {
|
|
7771
7944
|
if (packages.length === 0) {
|
|
7772
7945
|
console.log(import_picocolors.default.green(`
|
|
@@ -7783,7 +7956,7 @@ function renderTable(packages) {
|
|
|
7783
7956
|
const oldVer = pkg.currentVersion.padStart(oldWidth);
|
|
7784
7957
|
const arrow = "→";
|
|
7785
7958
|
const newVer = pkg.latestVersion.padEnd(newWidth);
|
|
7786
|
-
const age =
|
|
7959
|
+
const age = colorAge(pkg.age, pkg.ageMonths);
|
|
7787
7960
|
let diffLabel;
|
|
7788
7961
|
let coloredNewVer;
|
|
7789
7962
|
switch (pkg.diffType) {
|
|
@@ -7800,7 +7973,20 @@ function renderTable(packages) {
|
|
|
7800
7973
|
coloredNewVer = import_picocolors.default.green(newVer);
|
|
7801
7974
|
break;
|
|
7802
7975
|
}
|
|
7803
|
-
|
|
7976
|
+
let extra = "";
|
|
7977
|
+
if (pkg.majorAvailable) {
|
|
7978
|
+
extra += import_picocolors.default.magenta(` ${pkg.majorAvailable} available`);
|
|
7979
|
+
}
|
|
7980
|
+
if (pkg.phpRequirement) {
|
|
7981
|
+
extra += import_picocolors.default.gray(` php ${pkg.phpRequirement}`);
|
|
7982
|
+
}
|
|
7983
|
+
if (pkg.deprecated) {
|
|
7984
|
+
extra += import_picocolors.default.red(" deprecated");
|
|
7985
|
+
if (pkg.replacement) {
|
|
7986
|
+
extra += import_picocolors.default.yellow(` → ${pkg.replacement}`);
|
|
7987
|
+
}
|
|
7988
|
+
}
|
|
7989
|
+
console.log(` ${name} ${oldVer} ${arrow} ${coloredNewVer} ${diffLabel} ${age}${extra}`);
|
|
7804
7990
|
}
|
|
7805
7991
|
console.log("");
|
|
7806
7992
|
}
|
|
@@ -7834,7 +8020,31 @@ function formatPackageChoice(pkg) {
|
|
|
7834
8020
|
coloredNewVer = import_picocolors.default.green(pkg.latestVersion);
|
|
7835
8021
|
break;
|
|
7836
8022
|
}
|
|
7837
|
-
|
|
8023
|
+
const age = colorAge(pkg.age, pkg.ageMonths);
|
|
8024
|
+
let extra = "";
|
|
8025
|
+
if (pkg.majorAvailable) {
|
|
8026
|
+
extra += import_picocolors.default.magenta(` ${pkg.majorAvailable} available`);
|
|
8027
|
+
}
|
|
8028
|
+
if (pkg.phpRequirement) {
|
|
8029
|
+
extra += import_picocolors.default.gray(` php ${pkg.phpRequirement}`);
|
|
8030
|
+
}
|
|
8031
|
+
if (pkg.deprecated) {
|
|
8032
|
+
extra += import_picocolors.default.red(" deprecated");
|
|
8033
|
+
if (pkg.replacement) {
|
|
8034
|
+
extra += import_picocolors.default.yellow(` → ${pkg.replacement}`);
|
|
8035
|
+
}
|
|
8036
|
+
}
|
|
8037
|
+
return `${import_picocolors.default.bold(pkg.name)} ${pkg.currentVersion} ${arrow} ${coloredNewVer} ${diffLabel} ${age}${extra}`;
|
|
8038
|
+
}
|
|
8039
|
+
function renderDeprecated(packages) {
|
|
8040
|
+
if (packages.length === 0)
|
|
8041
|
+
return;
|
|
8042
|
+
console.log(import_picocolors.default.yellow(" Deprecated packages detected:"));
|
|
8043
|
+
for (const pkg of packages) {
|
|
8044
|
+
const replacement = pkg.replacement ? import_picocolors.default.yellow(` → ${pkg.replacement}`) : "";
|
|
8045
|
+
console.log(` ${import_picocolors.default.red("!")} ${import_picocolors.default.bold(pkg.name)} ${import_picocolors.default.gray(pkg.currentVersion)}${replacement}`);
|
|
8046
|
+
}
|
|
8047
|
+
console.log("");
|
|
7838
8048
|
}
|
|
7839
8049
|
|
|
7840
8050
|
// src/interactive.ts
|
|
@@ -7860,11 +8070,62 @@ async function selectPackages(packages) {
|
|
|
7860
8070
|
const selectedNames = new Set(response.selected);
|
|
7861
8071
|
return packages.filter((pkg) => selectedNames.has(pkg.name));
|
|
7862
8072
|
}
|
|
8073
|
+
// package.json
|
|
8074
|
+
var package_default = {
|
|
8075
|
+
name: "comze",
|
|
8076
|
+
version: "0.3.0",
|
|
8077
|
+
description: "A taze-like CLI for updating composer.json dependencies",
|
|
8078
|
+
author: "qoqn",
|
|
8079
|
+
license: "MIT",
|
|
8080
|
+
keywords: [
|
|
8081
|
+
"composer",
|
|
8082
|
+
"php",
|
|
8083
|
+
"dependencies",
|
|
8084
|
+
"update",
|
|
8085
|
+
"cli",
|
|
8086
|
+
"taze"
|
|
8087
|
+
],
|
|
8088
|
+
type: "module",
|
|
8089
|
+
main: "./dist/cli.mjs",
|
|
8090
|
+
module: "./dist/cli.mjs",
|
|
8091
|
+
bin: {
|
|
8092
|
+
comze: "bin/comze.mjs"
|
|
8093
|
+
},
|
|
8094
|
+
files: [
|
|
8095
|
+
"dist",
|
|
8096
|
+
"bin"
|
|
8097
|
+
],
|
|
8098
|
+
scripts: {
|
|
8099
|
+
dev: "bun run src/cli.ts",
|
|
8100
|
+
build: "bun build src/cli.ts --outfile dist/cli.mjs --target node",
|
|
8101
|
+
prepublishOnly: "bun run build",
|
|
8102
|
+
test: "bun test"
|
|
8103
|
+
},
|
|
8104
|
+
engines: {
|
|
8105
|
+
node: ">=18"
|
|
8106
|
+
},
|
|
8107
|
+
repository: {
|
|
8108
|
+
type: "git",
|
|
8109
|
+
url: "git+https://github.com/qoqn/comze.git"
|
|
8110
|
+
},
|
|
8111
|
+
devDependencies: {
|
|
8112
|
+
"@types/bun": "latest",
|
|
8113
|
+
"@types/prompts": "^2.4.9",
|
|
8114
|
+
"@types/semver": "^7.7.1",
|
|
8115
|
+
typescript: "^5"
|
|
8116
|
+
},
|
|
8117
|
+
dependencies: {
|
|
8118
|
+
cac: "^6.7.14",
|
|
8119
|
+
"detect-indent": "^7.0.2",
|
|
8120
|
+
picocolors: "^1.1.1",
|
|
8121
|
+
prompts: "^2.4.2",
|
|
8122
|
+
semver: "^7.7.3"
|
|
8123
|
+
}
|
|
8124
|
+
};
|
|
7863
8125
|
|
|
7864
8126
|
// src/index.ts
|
|
7865
|
-
var VERSION = "0.1.0";
|
|
7866
8127
|
async function run(options) {
|
|
7867
|
-
renderHeader(
|
|
8128
|
+
renderHeader(package_default.version);
|
|
7868
8129
|
const composerPath = resolve(process.cwd(), "composer.json");
|
|
7869
8130
|
const composer = await readComposerJson(composerPath);
|
|
7870
8131
|
if (!composer) {
|
|
@@ -7888,12 +8149,20 @@ async function run(options) {
|
|
|
7888
8149
|
console.log(import_picocolors2.default.gray(` Checking ${Object.keys(filteredPackages).length} packages...`));
|
|
7889
8150
|
console.log(import_picocolors2.default.gray(` Stability: ${minStability}${preferStable ? " (prefer-stable)" : ""}
|
|
7890
8151
|
`));
|
|
7891
|
-
const results = await fetchAllPackages(filteredPackages, minStability, preferStable);
|
|
8152
|
+
const results = await fetchAllPackages(filteredPackages, minStability, preferStable, options.major, options.noCache);
|
|
7892
8153
|
const updates = [];
|
|
8154
|
+
const deprecatedPackages = [];
|
|
7893
8155
|
for (const [name, currentVersion] of Object.entries(filteredPackages)) {
|
|
7894
8156
|
const result = results.get(name);
|
|
7895
8157
|
if (!result)
|
|
7896
8158
|
continue;
|
|
8159
|
+
if (result.deprecated) {
|
|
8160
|
+
deprecatedPackages.push({
|
|
8161
|
+
name,
|
|
8162
|
+
currentVersion,
|
|
8163
|
+
replacement: result.replacement
|
|
8164
|
+
});
|
|
8165
|
+
}
|
|
7897
8166
|
const diffType = getDiffType(currentVersion, result.latestVersion);
|
|
7898
8167
|
if (!diffType)
|
|
7899
8168
|
continue;
|
|
@@ -7903,18 +8172,25 @@ async function run(options) {
|
|
|
7903
8172
|
continue;
|
|
7904
8173
|
if (diffType === "patch" && !options.patch)
|
|
7905
8174
|
continue;
|
|
8175
|
+
const majorAvailable = !options.major && result.majorVersion ? result.majorVersion : undefined;
|
|
7906
8176
|
updates.push({
|
|
7907
8177
|
name,
|
|
7908
8178
|
currentVersion,
|
|
7909
8179
|
latestVersion: result.latestVersion,
|
|
7910
8180
|
diffType,
|
|
7911
8181
|
releaseTime: result.releaseTime,
|
|
7912
|
-
age: formatAge(result.releaseTime)
|
|
8182
|
+
age: formatAge(result.releaseTime),
|
|
8183
|
+
ageMonths: getAgeMonths(result.releaseTime),
|
|
8184
|
+
majorAvailable,
|
|
8185
|
+
phpRequirement: result.phpRequirement,
|
|
8186
|
+
deprecated: result.deprecated,
|
|
8187
|
+
replacement: result.replacement
|
|
7913
8188
|
});
|
|
7914
8189
|
}
|
|
7915
8190
|
const order = { major: 0, minor: 1, patch: 2 };
|
|
7916
8191
|
updates.sort((a, b) => order[a.diffType] - order[b.diffType]);
|
|
7917
8192
|
renderTable(updates);
|
|
8193
|
+
renderDeprecated(deprecatedPackages);
|
|
7918
8194
|
if (updates.length === 0)
|
|
7919
8195
|
return;
|
|
7920
8196
|
let selectedUpdates = updates;
|
|
@@ -7929,8 +8205,14 @@ async function run(options) {
|
|
|
7929
8205
|
if (options.write || options.install) {
|
|
7930
8206
|
const success = await writeComposerJson(composerPath, selectedUpdates, options.dryRun);
|
|
7931
8207
|
if (success && !options.dryRun) {
|
|
7932
|
-
console.log(import_picocolors2.default.green(
|
|
8208
|
+
console.log(import_picocolors2.default.green(" ✓ Updated composer.json"));
|
|
8209
|
+
if (options.write && !options.install) {
|
|
8210
|
+
console.log(import_picocolors2.default.gray(`
|
|
8211
|
+
Run "composer update" to install the new versions
|
|
7933
8212
|
`));
|
|
8213
|
+
} else {
|
|
8214
|
+
console.log("");
|
|
8215
|
+
}
|
|
7934
8216
|
}
|
|
7935
8217
|
}
|
|
7936
8218
|
if (options.install && !options.dryRun) {
|
|
@@ -7955,9 +8237,13 @@ async function run(options) {
|
|
|
7955
8237
|
|
|
7956
8238
|
// src/cli.ts
|
|
7957
8239
|
var cli = dist_default("comze");
|
|
7958
|
-
cli.option("-w, --write", "Write changes to composer.json", { default: false }).option("-i, --install", "Write changes and run composer update", {
|
|
8240
|
+
cli.option("-w, --write", "Write changes to composer.json", { default: false }).option("-i, --install", "Write changes and run composer update", {
|
|
8241
|
+
default: false
|
|
8242
|
+
}).option("-I, --interactive", "Select updates manually", { default: false }).option("--major", "Include major updates", { default: false }).option("--minor", "Include minor updates", { default: true }).option("--patch", "Include patch updates", { default: true }).option("--exclude <packages>", "Exclude packages (comma-separated)", {
|
|
8243
|
+
default: ""
|
|
8244
|
+
}).option("--dry-run", "Run without making changes", { default: false }).option("--no-cache", "Bypass cache and force fetch from network", { default: false });
|
|
7959
8245
|
cli.help();
|
|
7960
|
-
cli.version(
|
|
8246
|
+
cli.version(package_default.version);
|
|
7961
8247
|
cli.command("", "Check for updates in composer.json").action(async (cliOptions) => {
|
|
7962
8248
|
const options = {
|
|
7963
8249
|
write: cliOptions.write || cliOptions.install,
|
|
@@ -7967,7 +8253,8 @@ cli.command("", "Check for updates in composer.json").action(async (cliOptions)
|
|
|
7967
8253
|
minor: cliOptions.minor,
|
|
7968
8254
|
patch: cliOptions.patch,
|
|
7969
8255
|
exclude: cliOptions.exclude ? cliOptions.exclude.split(",").map((s) => s.trim()) : [],
|
|
7970
|
-
dryRun: cliOptions.dryRun
|
|
8256
|
+
dryRun: cliOptions.dryRun,
|
|
8257
|
+
noCache: cliOptions.noCache
|
|
7971
8258
|
};
|
|
7972
8259
|
await run(options);
|
|
7973
8260
|
});
|