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 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 | Description |
54
- |------|-------------|
55
- | `-w, --write` | Write changes to `composer.json` |
56
- | `-i, --install` | Write changes and run `composer update` |
57
- | `-I, --interactive` | Select updates manually |
58
- | `--major` | Include major updates (default: false) |
59
- | `--minor` | Include minor updates (default: true) |
60
- | `--patch` | Include patch updates (default: true) |
61
- | `--exclude <pkgs>` | Exclude packages (comma-separated) |
62
- | `--dry-run` | Preview changes without writing |
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 | Example |
80
- |------|---------|
81
- | Exact | `1.0.2` |
82
- | Caret | `^1.2.3` |
83
- | Tilde | `~1.2` |
84
- | Wildcard | `1.0.*` |
85
- | Range | `>=1.0 <2.0` |
86
- | Hyphenated | `1.0 - 2.0` |
87
- | Dev | `dev-main`, `1.x-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 '../dist/cli.mjs';
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 { type: "caret", prefix: "^", baseVersion: normalizeVersionString(version), original, isDev: hasDevSuffix(version) };
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 { type: "tilde", prefix: "~", baseVersion: normalizeVersionString(version), original, isDev: hasDevSuffix(version) };
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 { type: "hyphen", prefix: "", baseVersion: normalizeVersionString(startVersion), original, isDev: false };
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 { type: "range", prefix, baseVersion: normalizeVersionString(version), original, isDev: hasDevSuffix(version) };
7462
+ return {
7463
+ type: "range",
7464
+ prefix,
7465
+ baseVersion: normalizeVersionString(version),
7466
+ original,
7467
+ isDev: hasDevSuffix(version)
7468
+ };
7442
7469
  }
7443
- return { type: "exact", prefix: "", baseVersion: normalizeVersionString(original), original, isDev: hasDevSuffix(original) };
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
- async function fetchPackage(packageName, minStability = "stable", preferStable = true) {
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
- const latest2 = stableVersions[0];
7549
- if (!latest2)
7550
- return null;
7551
- return { latestVersion: latest2.version, releaseTime: latest2.time };
7671
+ selectedVersion = stableVersions[0] ?? null;
7552
7672
  }
7553
7673
  }
7554
- const latest = eligibleVersions[0];
7555
- if (!latest)
7674
+ if (!selectedVersion) {
7675
+ selectedVersion = eligibleVersions[0] ?? null;
7676
+ }
7677
+ if (!selectedVersion)
7556
7678
  return null;
7557
- return { latestVersion: latest.version, releaseTime: latest.time };
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(path) {
7685
- if (!existsSync(path))
7841
+ async function readComposerJson(path2) {
7842
+ if (!existsSync(path2))
7686
7843
  return null;
7687
7844
  try {
7688
- const raw = await readFile(path, "utf-8");
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(path, updates, dryRun = false) {
7697
- const result = await readComposerJson(path);
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(path, newContent, "utf-8");
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 = import_picocolors.default.gray(pkg.age.padStart(6));
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
- console.log(` ${name} ${oldVer} ${arrow} ${coloredNewVer} ${diffLabel} ${age}`);
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
- return `${import_picocolors.default.bold(pkg.name)} ${pkg.currentVersion} ${arrow} ${coloredNewVer} ${diffLabel} ${import_picocolors.default.gray(pkg.age)}`;
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(VERSION);
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(` ✓ Updated composer.json
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", { default: false }).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)", { default: "" }).option("--dry-run", "Run without making changes", { default: false });
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("0.1.0");
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
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comze",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "A taze-like CLI for updating composer.json dependencies",
5
5
  "author": "qoqn",
6
6
  "license": "MIT",