comze 0.3.2 → 0.4.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.
Files changed (3) hide show
  1. package/README.md +23 -1
  2. package/dist/cli.mjs +286 -229
  3. package/package.json +4 -4
package/README.md CHANGED
@@ -47,6 +47,9 @@ comze --dry-run
47
47
 
48
48
  # Exclude packages
49
49
  comze --exclude vendor/package
50
+
51
+ # Exclude multiple packages
52
+ comze --exclude vendor/package-a,vendor/package-b
50
53
  ```
51
54
 
52
55
  ## Options
@@ -59,9 +62,28 @@ comze --exclude vendor/package
59
62
  | `--major` | Include major updates (default: false) |
60
63
  | `--minor` | Include minor updates (default: true) |
61
64
  | `--patch` | Include patch updates (default: true) |
62
- | `--exclude <pkgs>` | Exclude packages (comma-separated) |
65
+ | `--exclude <pkgs>` | Exclude packages (comma-separated, merged with `extra.comze.exclude`) |
63
66
  | `--dry-run` | Preview changes without writing |
64
67
 
68
+ ## Persistent Excludes
69
+
70
+ For packages that should always be ignored, store them in `composer.json` under `extra.comze.exclude`:
71
+
72
+ ```json
73
+ {
74
+ "extra": {
75
+ "comze": {
76
+ "exclude": [
77
+ "vendor/package-a",
78
+ "vendor/package-b"
79
+ ]
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ `comze` merges this list with `--exclude`, so the flag remains useful for one-off runs while the file keeps repository-wide defaults.
86
+
65
87
  ## Composer Stability
66
88
 
67
89
  comze reads `minimum-stability` and `prefer-stable` from your `composer.json`:
package/dist/cli.mjs CHANGED
@@ -4,15 +4,29 @@ var __getProtoOf = Object.getPrototypeOf;
4
4
  var __defProp = Object.defineProperty;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ function __accessProp(key) {
8
+ return this[key];
9
+ }
10
+ var __toESMCache_node;
11
+ var __toESMCache_esm;
7
12
  var __toESM = (mod, isNodeMode, target) => {
13
+ var canCache = mod != null && typeof mod === "object";
14
+ if (canCache) {
15
+ var cache = isNodeMode ? __toESMCache_node ??= new WeakMap : __toESMCache_esm ??= new WeakMap;
16
+ var cached = cache.get(mod);
17
+ if (cached)
18
+ return cached;
19
+ }
8
20
  target = mod != null ? __create(__getProtoOf(mod)) : {};
9
21
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
10
22
  for (let key of __getOwnPropNames(mod))
11
23
  if (!__hasOwnProp.call(to, key))
12
24
  __defProp(to, key, {
13
- get: () => mod[key],
25
+ get: __accessProp.bind(mod, key),
14
26
  enumerable: true
15
27
  });
28
+ if (canCache)
29
+ cache.set(mod, to);
16
30
  return to;
17
31
  };
18
32
  var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
@@ -2095,7 +2109,7 @@ var require_clear = __commonJS((exports, module) => {
2095
2109
  if (it)
2096
2110
  o = it;
2097
2111
  var i = 0;
2098
- var F = function F() {};
2112
+ var F = function F2() {};
2099
2113
  return { s: F, n: function n() {
2100
2114
  if (i >= o.length)
2101
2115
  return { done: true };
@@ -2310,13 +2324,13 @@ var require_prompt = __commonJS((exports, module) => {
2310
2324
  var readline = __require("readline");
2311
2325
  var _require = require_util();
2312
2326
  var action = _require.action;
2313
- var EventEmitter2 = __require("events");
2327
+ var EventEmitter = __require("events");
2314
2328
  var _require2 = require_src();
2315
2329
  var beep = _require2.beep;
2316
2330
  var cursor = _require2.cursor;
2317
2331
  var color = require_kleur();
2318
2332
 
2319
- class Prompt extends EventEmitter2 {
2333
+ class Prompt extends EventEmitter {
2320
2334
  constructor(opts = {}) {
2321
2335
  super();
2322
2336
  this.firstRender = true;
@@ -4427,7 +4441,7 @@ var require_dist = __commonJS((exports, module) => {
4427
4441
  if (it)
4428
4442
  o = it;
4429
4443
  var i = 0;
4430
- var F = function F() {};
4444
+ var F = function F2() {};
4431
4445
  return { s: F, n: function n() {
4432
4446
  if (i >= o.length)
4433
4447
  return { done: true };
@@ -4530,7 +4544,7 @@ In order to be iterable, non-array objects must have a [Symbol.iterator]() metho
4530
4544
  }
4531
4545
  return question2.format ? yield question2.format(answer2, answers) : answer2;
4532
4546
  });
4533
- return function getFormattedAnswer(_x, _x2) {
4547
+ return function getFormattedAnswer2(_x, _x2) {
4534
4548
  return _ref.apply(this, arguments);
4535
4549
  };
4536
4550
  }();
@@ -4818,11 +4832,11 @@ var require_util2 = __commonJS((exports, module) => {
4818
4832
  var require_prompt2 = __commonJS((exports, module) => {
4819
4833
  var readline = __require("readline");
4820
4834
  var { action } = require_util2();
4821
- var EventEmitter2 = __require("events");
4835
+ var EventEmitter = __require("events");
4822
4836
  var { beep, cursor } = require_src();
4823
4837
  var color = require_kleur();
4824
4838
 
4825
- class Prompt extends EventEmitter2 {
4839
+ class Prompt extends EventEmitter {
4826
4840
  constructor(opts = {}) {
4827
4841
  super();
4828
4842
  this.firstRender = true;
@@ -6788,8 +6802,7 @@ var require_prompts3 = __commonJS((exports, module) => {
6788
6802
  module.exports = isNodeLT("8.6.0") ? require_dist() : require_lib();
6789
6803
  });
6790
6804
 
6791
- // node_modules/cac/dist/index.mjs
6792
- import { EventEmitter } from "events";
6805
+ // node_modules/cac/dist/index.js
6793
6806
  function toArr(any) {
6794
6807
  return any == null ? [] : Array.isArray(any) ? any : [any];
6795
6808
  }
@@ -6797,7 +6810,7 @@ function toVal(out, key, val, opts) {
6797
6810
  var x, old = out[key], nxt = ~opts.string.indexOf(key) ? val == null || val === true ? "" : String(val) : typeof val === "boolean" ? val : ~opts.boolean.indexOf(key) ? val === "false" ? false : val === "true" || (out._.push((x = +val, x * 0 === 0) ? x : val), !!val) : (x = +val, x * 0 === 0) ? x : val;
6798
6811
  out[key] = old == null ? nxt : Array.isArray(old) ? old.concat(nxt) : [old, nxt];
6799
6812
  }
6800
- function mri2(args, opts) {
6813
+ function lib_default(args, opts) {
6801
6814
  args = args || [];
6802
6815
  opts = opts || {};
6803
6816
  var k, arr, arg, name, val, out = { _: [] };
@@ -6808,14 +6821,12 @@ function mri2(args, opts) {
6808
6821
  opts.alias = opts.alias || {};
6809
6822
  opts.string = toArr(opts.string);
6810
6823
  opts.boolean = toArr(opts.boolean);
6811
- if (alibi) {
6824
+ if (alibi)
6812
6825
  for (k in opts.alias) {
6813
6826
  arr = opts.alias[k] = toArr(opts.alias[k]);
6814
- for (i = 0;i < arr.length; i++) {
6827
+ for (i = 0;i < arr.length; i++)
6815
6828
  (opts.alias[arr[i]] = arr.concat(k)).splice(i, 1);
6816
- }
6817
6829
  }
6818
- }
6819
6830
  for (i = opts.boolean.length;i-- > 0; ) {
6820
6831
  arr = opts.alias[opts.boolean[i]] || [];
6821
6832
  for (j = arr.length;j-- > 0; )
@@ -6826,18 +6837,16 @@ function mri2(args, opts) {
6826
6837
  for (j = arr.length;j-- > 0; )
6827
6838
  opts.string.push(arr[j]);
6828
6839
  }
6829
- if (defaults) {
6840
+ if (defaults)
6830
6841
  for (k in opts.default) {
6831
6842
  name = typeof opts.default[k];
6832
6843
  arr = opts.alias[k] = opts.alias[k] || [];
6833
6844
  if (opts[name] !== undefined) {
6834
6845
  opts[name].push(k);
6835
- for (i = 0;i < arr.length; i++) {
6846
+ for (i = 0;i < arr.length; i++)
6836
6847
  opts[name].push(arr[i]);
6837
- }
6838
6848
  }
6839
6849
  }
6840
- }
6841
6850
  const keys = strict ? Object.keys(opts.alias) : [];
6842
6851
  for (i = 0;i < len; i++) {
6843
6852
  arg = args[i];
@@ -6845,25 +6854,22 @@ function mri2(args, opts) {
6845
6854
  out._ = out._.concat(args.slice(++i));
6846
6855
  break;
6847
6856
  }
6848
- for (j = 0;j < arg.length; j++) {
6857
+ for (j = 0;j < arg.length; j++)
6849
6858
  if (arg.charCodeAt(j) !== 45)
6850
6859
  break;
6851
- }
6852
- if (j === 0) {
6860
+ if (j === 0)
6853
6861
  out._.push(arg);
6854
- } else if (arg.substring(j, j + 3) === "no-") {
6862
+ else if (arg.substring(j, j + 3) === "no-") {
6855
6863
  name = arg.substring(j + 3);
6856
- if (strict && !~keys.indexOf(name)) {
6864
+ if (strict && !~keys.indexOf(name))
6857
6865
  return opts.unknown(arg);
6858
- }
6859
6866
  out[name] = false;
6860
6867
  } else {
6861
- for (idx = j + 1;idx < arg.length; idx++) {
6868
+ for (idx = j + 1;idx < arg.length; idx++)
6862
6869
  if (arg.charCodeAt(idx) === 61)
6863
6870
  break;
6864
- }
6865
6871
  name = arg.substring(j, idx);
6866
- val = arg.substring(++idx) || (i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i]);
6872
+ val = arg.substring(++idx) || i + 1 === len || ("" + args[i + 1]).charCodeAt(0) === 45 || args[++i];
6867
6873
  arr = j === 2 ? [name] : name;
6868
6874
  for (idx = 0;idx < arr.length; idx++) {
6869
6875
  name = arr[idx];
@@ -6874,24 +6880,22 @@ function mri2(args, opts) {
6874
6880
  }
6875
6881
  }
6876
6882
  if (defaults) {
6877
- for (k in opts.default) {
6878
- if (out[k] === undefined) {
6883
+ for (k in opts.default)
6884
+ if (out[k] === undefined)
6879
6885
  out[k] = opts.default[k];
6880
- }
6881
- }
6882
6886
  }
6883
- if (alibi) {
6887
+ if (alibi)
6884
6888
  for (k in out) {
6885
6889
  arr = opts.alias[k] || [];
6886
- while (arr.length > 0) {
6890
+ while (arr.length > 0)
6887
6891
  out[arr.shift()] = out[k];
6888
- }
6889
6892
  }
6890
- }
6891
6893
  return out;
6892
6894
  }
6893
- var removeBrackets = (v) => v.replace(/[<[].+/, "").trim();
6894
- var findAllBrackets = (v) => {
6895
+ function removeBrackets(v) {
6896
+ return v.replace(/[<[].+/, "").trim();
6897
+ }
6898
+ function findAllBrackets(v) {
6895
6899
  const ANGLED_BRACKET_RE_GLOBAL = /<([^>]+)>/g;
6896
6900
  const SQUARE_BRACKET_RE_GLOBAL = /\[([^\]]+)\]/g;
6897
6901
  const res = [];
@@ -6909,98 +6913,101 @@ var findAllBrackets = (v) => {
6909
6913
  };
6910
6914
  };
6911
6915
  let angledMatch;
6912
- while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v)) {
6916
+ while (angledMatch = ANGLED_BRACKET_RE_GLOBAL.exec(v))
6913
6917
  res.push(parse(angledMatch));
6914
- }
6915
6918
  let squareMatch;
6916
- while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v)) {
6919
+ while (squareMatch = SQUARE_BRACKET_RE_GLOBAL.exec(v))
6917
6920
  res.push(parse(squareMatch));
6918
- }
6919
6921
  return res;
6920
- };
6921
- var getMriOptions = (options) => {
6922
- const result = { alias: {}, boolean: [] };
6922
+ }
6923
+ function getMriOptions(options) {
6924
+ const result = {
6925
+ alias: {},
6926
+ boolean: []
6927
+ };
6923
6928
  for (const [index, option] of options.entries()) {
6924
- if (option.names.length > 1) {
6929
+ if (option.names.length > 1)
6925
6930
  result.alias[option.names[0]] = option.names.slice(1);
6926
- }
6927
- if (option.isBoolean) {
6931
+ if (option.isBoolean)
6928
6932
  if (option.negated) {
6929
- const hasStringTypeOption = options.some((o, i) => {
6933
+ if (!options.some((o, i) => {
6930
6934
  return i !== index && o.names.some((name) => option.names.includes(name)) && typeof o.required === "boolean";
6931
- });
6932
- if (!hasStringTypeOption) {
6935
+ }))
6933
6936
  result.boolean.push(option.names[0]);
6934
- }
6935
- } else {
6937
+ } else
6936
6938
  result.boolean.push(option.names[0]);
6937
- }
6938
- }
6939
6939
  }
6940
6940
  return result;
6941
- };
6942
- var findLongest = (arr) => {
6941
+ }
6942
+ function findLongest(arr) {
6943
6943
  return arr.sort((a, b) => {
6944
6944
  return a.length > b.length ? -1 : 1;
6945
6945
  })[0];
6946
- };
6947
- var padRight = (str, length) => {
6946
+ }
6947
+ function padRight(str, length) {
6948
6948
  return str.length >= length ? str : `${str}${" ".repeat(length - str.length)}`;
6949
- };
6950
- var camelcase = (input) => {
6951
- return input.replace(/([a-z])-([a-z])/g, (_, p1, p2) => {
6949
+ }
6950
+ function camelcase(input) {
6951
+ return input.replaceAll(/([a-z])-([a-z])/g, (_, p1, p2) => {
6952
6952
  return p1 + p2.toUpperCase();
6953
6953
  });
6954
- };
6955
- var setDotProp = (obj, keys, val) => {
6956
- let i = 0;
6957
- let length = keys.length;
6958
- let t = obj;
6959
- let x;
6960
- for (;i < length; ++i) {
6961
- x = t[keys[i]];
6962
- t = t[keys[i]] = i === length - 1 ? val : x != null ? x : !!~keys[i + 1].indexOf(".") || !(+keys[i + 1] > -1) ? {} : [];
6954
+ }
6955
+ function setDotProp(obj, keys, val) {
6956
+ let current = obj;
6957
+ for (let i = 0;i < keys.length; i++) {
6958
+ const key = keys[i];
6959
+ if (i === keys.length - 1) {
6960
+ current[key] = val;
6961
+ return;
6962
+ }
6963
+ if (current[key] == null) {
6964
+ const nextKeyIsArrayIndex = +keys[i + 1] > -1;
6965
+ current[key] = nextKeyIsArrayIndex ? [] : {};
6966
+ }
6967
+ current = current[key];
6963
6968
  }
6964
- };
6965
- var setByType = (obj, transforms) => {
6969
+ }
6970
+ function setByType(obj, transforms) {
6966
6971
  for (const key of Object.keys(transforms)) {
6967
6972
  const transform = transforms[key];
6968
6973
  if (transform.shouldTransform) {
6969
- obj[key] = Array.prototype.concat.call([], obj[key]);
6970
- if (typeof transform.transformFunction === "function") {
6974
+ obj[key] = [obj[key]].flat();
6975
+ if (typeof transform.transformFunction === "function")
6971
6976
  obj[key] = obj[key].map(transform.transformFunction);
6972
- }
6973
6977
  }
6974
6978
  }
6975
- };
6976
- var getFileName = (input) => {
6977
- const m = /([^\\\/]+)$/.exec(input);
6979
+ }
6980
+ function getFileName(input) {
6981
+ const m = /([^\\/]+)$/.exec(input);
6978
6982
  return m ? m[1] : "";
6979
- };
6980
- var camelcaseOptionName = (name) => {
6983
+ }
6984
+ function camelcaseOptionName(name) {
6981
6985
  return name.split(".").map((v, i) => {
6982
6986
  return i === 0 ? camelcase(v) : v;
6983
6987
  }).join(".");
6984
- };
6985
-
6986
- class CACError extends Error {
6988
+ }
6989
+ var CACError = class extends Error {
6987
6990
  constructor(message) {
6988
6991
  super(message);
6989
- this.name = this.constructor.name;
6990
- if (typeof Error.captureStackTrace === "function") {
6991
- Error.captureStackTrace(this, this.constructor);
6992
- } else {
6992
+ this.name = "CACError";
6993
+ if (typeof Error.captureStackTrace !== "function")
6993
6994
  this.stack = new Error(message).stack;
6994
- }
6995
6995
  }
6996
- }
6997
-
6998
- class Option {
6996
+ };
6997
+ var Option = class {
6998
+ rawName;
6999
+ description;
7000
+ name;
7001
+ names;
7002
+ isBoolean;
7003
+ required;
7004
+ config;
7005
+ negated;
6999
7006
  constructor(rawName, description, config) {
7000
7007
  this.rawName = rawName;
7001
7008
  this.description = description;
7002
7009
  this.config = Object.assign({}, config);
7003
- rawName = rawName.replace(/\.\*/g, "");
7010
+ rawName = rawName.replaceAll(".*", "");
7004
7011
  this.negated = false;
7005
7012
  this.names = removeBrackets(rawName).split(",").map((v) => {
7006
7013
  let name = v.trim().replace(/^-{1,2}/, "");
@@ -7010,23 +7017,48 @@ class Option {
7010
7017
  }
7011
7018
  return camelcaseOptionName(name);
7012
7019
  }).sort((a, b) => a.length > b.length ? 1 : -1);
7013
- this.name = this.names[this.names.length - 1];
7014
- if (this.negated && this.config.default == null) {
7020
+ this.name = this.names.at(-1);
7021
+ if (this.negated && this.config.default == null)
7015
7022
  this.config.default = true;
7016
- }
7017
- if (rawName.includes("<")) {
7023
+ if (rawName.includes("<"))
7018
7024
  this.required = true;
7019
- } else if (rawName.includes("[")) {
7025
+ else if (rawName.includes("["))
7020
7026
  this.required = false;
7021
- } else {
7027
+ else
7022
7028
  this.isBoolean = true;
7023
- }
7024
7029
  }
7025
- }
7026
- var processArgs = process.argv;
7027
- var platformInfo = `${process.platform}-${process.arch} node-${process.version}`;
7028
-
7029
- class Command {
7030
+ };
7031
+ var runtimeProcessArgs;
7032
+ var runtimeInfo;
7033
+ if (typeof process !== "undefined") {
7034
+ let runtimeName;
7035
+ if (typeof Deno !== "undefined" && typeof Deno.version?.deno === "string")
7036
+ runtimeName = "deno";
7037
+ else if (typeof Bun !== "undefined" && typeof Bun.version === "string")
7038
+ runtimeName = "bun";
7039
+ else
7040
+ runtimeName = "node";
7041
+ runtimeInfo = `${process.platform}-${process.arch} ${runtimeName}-${process.version}`;
7042
+ runtimeProcessArgs = process.argv;
7043
+ } else if (typeof navigator === "undefined")
7044
+ runtimeInfo = `unknown`;
7045
+ else
7046
+ runtimeInfo = `${navigator.platform} ${navigator.userAgent}`;
7047
+ var Command = class {
7048
+ rawName;
7049
+ description;
7050
+ config;
7051
+ cli;
7052
+ options;
7053
+ aliasNames;
7054
+ name;
7055
+ args;
7056
+ commandAction;
7057
+ usageText;
7058
+ versionNumber;
7059
+ examples;
7060
+ helpCallback;
7061
+ globalCommand;
7030
7062
  constructor(rawName, description, config = {}, cli) {
7031
7063
  this.rawName = rawName;
7032
7064
  this.description = description;
@@ -7089,22 +7121,13 @@ class Command {
7089
7121
  }
7090
7122
  outputHelp() {
7091
7123
  const { name, commands } = this.cli;
7092
- const {
7093
- versionNumber,
7094
- options: globalOptions,
7095
- helpCallback
7096
- } = this.cli.globalCommand;
7097
- let sections = [
7098
- {
7099
- body: `${name}${versionNumber ? `/${versionNumber}` : ""}`
7100
- }
7101
- ];
7124
+ const { versionNumber, options: globalOptions, helpCallback } = this.cli.globalCommand;
7125
+ let sections = [{ body: `${name}${versionNumber ? `/${versionNumber}` : ""}` }];
7102
7126
  sections.push({
7103
7127
  title: "Usage",
7104
7128
  body: ` $ ${name} ${this.usageText || this.rawName}`
7105
7129
  });
7106
- const showCommands = (this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0;
7107
- if (showCommands) {
7130
+ if ((this.isGlobalCommand || this.isDefaultCommand) && commands.length > 0) {
7108
7131
  const longestCommandName = findLongest(commands.map((command) => command.rawName));
7109
7132
  sections.push({
7110
7133
  title: "Commands",
@@ -7112,17 +7135,15 @@ class Command {
7112
7135
  return ` ${padRight(command.rawName, longestCommandName.length)} ${command.description}`;
7113
7136
  }).join(`
7114
7137
  `)
7115
- });
7116
- sections.push({
7138
+ }, {
7117
7139
  title: `For more info, run any command with the \`--help\` flag`,
7118
7140
  body: commands.map((command) => ` $ ${name}${command.name === "" ? "" : ` ${command.name}`} --help`).join(`
7119
7141
  `)
7120
7142
  });
7121
7143
  }
7122
7144
  let options = this.isGlobalCommand ? globalOptions : [...this.options, ...globalOptions || []];
7123
- if (!this.isGlobalCommand && !this.isDefaultCommand) {
7145
+ if (!this.isGlobalCommand && !this.isDefaultCommand)
7124
7146
  options = options.filter((option) => option.name !== "version");
7125
- }
7126
7147
  if (options.length > 0) {
7127
7148
  const longestOptionName = findLongest(options.map((option) => option.rawName));
7128
7149
  sections.push({
@@ -7133,22 +7154,19 @@ class Command {
7133
7154
  `)
7134
7155
  });
7135
7156
  }
7136
- if (this.examples.length > 0) {
7157
+ if (this.examples.length > 0)
7137
7158
  sections.push({
7138
7159
  title: "Examples",
7139
7160
  body: this.examples.map((example) => {
7140
- if (typeof example === "function") {
7161
+ if (typeof example === "function")
7141
7162
  return example(name);
7142
- }
7143
7163
  return example;
7144
7164
  }).join(`
7145
7165
  `)
7146
7166
  });
7147
- }
7148
- if (helpCallback) {
7167
+ if (helpCallback)
7149
7168
  sections = helpCallback(sections) || sections;
7150
- }
7151
- console.log(sections.map((section) => {
7169
+ console.info(sections.map((section) => {
7152
7170
  return section.title ? `${section.title}:
7153
7171
  ${section.body}` : section.body;
7154
7172
  }).join(`
@@ -7158,24 +7176,20 @@ ${section.body}` : section.body;
7158
7176
  outputVersion() {
7159
7177
  const { name } = this.cli;
7160
7178
  const { versionNumber } = this.cli.globalCommand;
7161
- if (versionNumber) {
7162
- console.log(`${name}/${versionNumber} ${platformInfo}`);
7163
- }
7179
+ if (versionNumber)
7180
+ console.info(`${name}/${versionNumber} ${runtimeInfo}`);
7164
7181
  }
7165
7182
  checkRequiredArgs() {
7166
7183
  const minimalArgsCount = this.args.filter((arg) => arg.required).length;
7167
- if (this.cli.args.length < minimalArgsCount) {
7184
+ if (this.cli.args.length < minimalArgsCount)
7168
7185
  throw new CACError(`missing required args for command \`${this.rawName}\``);
7169
- }
7170
7186
  }
7171
7187
  checkUnknownOptions() {
7172
7188
  const { options, globalCommand } = this.cli;
7173
7189
  if (!this.config.allowUnknownOptions) {
7174
- for (const name of Object.keys(options)) {
7175
- if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name)) {
7190
+ for (const name of Object.keys(options))
7191
+ if (name !== "--" && !this.hasOption(name) && !globalCommand.hasOption(name))
7176
7192
  throw new CACError(`Unknown option \`${name.length > 1 ? `--${name}` : `-${name}`}\``);
7177
- }
7178
- }
7179
7193
  }
7180
7194
  }
7181
7195
  checkOptionValue() {
@@ -7185,22 +7199,33 @@ ${section.body}` : section.body;
7185
7199
  const value = parsedOptions[option.name.split(".")[0]];
7186
7200
  if (option.required) {
7187
7201
  const hasNegated = options.some((o) => o.negated && o.names.includes(option.name));
7188
- if (value === true || value === false && !hasNegated) {
7202
+ if (value === true || value === false && !hasNegated)
7189
7203
  throw new CACError(`option \`${option.rawName}\` value is missing`);
7190
- }
7191
7204
  }
7192
7205
  }
7193
7206
  }
7194
- }
7195
-
7196
- class GlobalCommand extends Command {
7207
+ checkUnusedArgs() {
7208
+ const maximumArgsCount = this.args.some((arg) => arg.variadic) ? Infinity : this.args.length;
7209
+ if (maximumArgsCount < this.cli.args.length)
7210
+ throw new CACError(`Unused args: ${this.cli.args.slice(maximumArgsCount).map((arg) => `\`${arg}\``).join(", ")}`);
7211
+ }
7212
+ };
7213
+ var GlobalCommand = class extends Command {
7197
7214
  constructor(cli) {
7198
7215
  super("@@global@@", "", {}, cli);
7199
7216
  }
7200
- }
7201
- var __assign = Object.assign;
7202
-
7203
- class CAC extends EventEmitter {
7217
+ };
7218
+ var CAC = class extends EventTarget {
7219
+ name;
7220
+ commands;
7221
+ globalCommand;
7222
+ matchedCommand;
7223
+ matchedCommandName;
7224
+ rawArgs;
7225
+ args;
7226
+ options;
7227
+ showHelpOnExit;
7228
+ showVersionOnExit;
7204
7229
  constructor(name = "") {
7205
7230
  super();
7206
7231
  this.name = name;
@@ -7241,11 +7266,10 @@ class CAC extends EventEmitter {
7241
7266
  return this;
7242
7267
  }
7243
7268
  outputHelp() {
7244
- if (this.matchedCommand) {
7269
+ if (this.matchedCommand)
7245
7270
  this.matchedCommand.outputHelp();
7246
- } else {
7271
+ else
7247
7272
  this.globalCommand.outputHelp();
7248
- }
7249
7273
  }
7250
7274
  outputVersion() {
7251
7275
  this.globalCommand.outputVersion();
@@ -7253,47 +7277,47 @@ class CAC extends EventEmitter {
7253
7277
  setParsedInfo({ args, options }, matchedCommand, matchedCommandName) {
7254
7278
  this.args = args;
7255
7279
  this.options = options;
7256
- if (matchedCommand) {
7280
+ if (matchedCommand)
7257
7281
  this.matchedCommand = matchedCommand;
7258
- }
7259
- if (matchedCommandName) {
7282
+ if (matchedCommandName)
7260
7283
  this.matchedCommandName = matchedCommandName;
7261
- }
7262
7284
  return this;
7263
7285
  }
7264
7286
  unsetMatchedCommand() {
7265
7287
  this.matchedCommand = undefined;
7266
7288
  this.matchedCommandName = undefined;
7267
7289
  }
7268
- parse(argv = processArgs, {
7269
- run = true
7270
- } = {}) {
7290
+ parse(argv, { run = true } = {}) {
7291
+ if (!argv) {
7292
+ if (!runtimeProcessArgs)
7293
+ throw new Error("No argv provided and runtime process argv is not available.");
7294
+ argv = runtimeProcessArgs;
7295
+ }
7271
7296
  this.rawArgs = argv;
7272
- if (!this.name) {
7297
+ if (!this.name)
7273
7298
  this.name = argv[1] ? getFileName(argv[1]) : "cli";
7274
- }
7275
7299
  let shouldParse = true;
7276
7300
  for (const command of this.commands) {
7277
7301
  const parsed = this.mri(argv.slice(2), command);
7278
7302
  const commandName = parsed.args[0];
7279
7303
  if (command.isMatched(commandName)) {
7280
7304
  shouldParse = false;
7281
- const parsedInfo = __assign(__assign({}, parsed), {
7305
+ const parsedInfo = {
7306
+ ...parsed,
7282
7307
  args: parsed.args.slice(1)
7283
- });
7308
+ };
7284
7309
  this.setParsedInfo(parsedInfo, command, commandName);
7285
- this.emit(`command:${commandName}`, command);
7310
+ this.dispatchEvent(new CustomEvent(`command:${commandName}`, { detail: command }));
7286
7311
  }
7287
7312
  }
7288
7313
  if (shouldParse) {
7289
- for (const command of this.commands) {
7290
- if (command.name === "") {
7314
+ for (const command of this.commands)
7315
+ if (command.isDefaultCommand) {
7291
7316
  shouldParse = false;
7292
7317
  const parsed = this.mri(argv.slice(2), command);
7293
7318
  this.setParsedInfo(parsed, command);
7294
- this.emit(`command:!`, command);
7319
+ this.dispatchEvent(new CustomEvent("command:!", { detail: command }));
7295
7320
  }
7296
- }
7297
7321
  }
7298
7322
  if (shouldParse) {
7299
7323
  const parsed = this.mri(argv.slice(2));
@@ -7309,60 +7333,51 @@ class CAC extends EventEmitter {
7309
7333
  run = false;
7310
7334
  this.unsetMatchedCommand();
7311
7335
  }
7312
- const parsedArgv = { args: this.args, options: this.options };
7313
- if (run) {
7336
+ const parsedArgv = {
7337
+ args: this.args,
7338
+ options: this.options
7339
+ };
7340
+ if (run)
7314
7341
  this.runMatchedCommand();
7315
- }
7316
- if (!this.matchedCommand && this.args[0]) {
7317
- this.emit("command:*");
7318
- }
7342
+ if (!this.matchedCommand && this.args[0])
7343
+ this.dispatchEvent(new CustomEvent("command:*", { detail: this.args[0] }));
7319
7344
  return parsedArgv;
7320
7345
  }
7321
7346
  mri(argv, command) {
7322
- const cliOptions = [
7323
- ...this.globalCommand.options,
7324
- ...command ? command.options : []
7325
- ];
7347
+ const cliOptions = [...this.globalCommand.options, ...command ? command.options : []];
7326
7348
  const mriOptions = getMriOptions(cliOptions);
7327
7349
  let argsAfterDoubleDashes = [];
7328
7350
  const doubleDashesIndex = argv.indexOf("--");
7329
- if (doubleDashesIndex > -1) {
7351
+ if (doubleDashesIndex !== -1) {
7330
7352
  argsAfterDoubleDashes = argv.slice(doubleDashesIndex + 1);
7331
7353
  argv = argv.slice(0, doubleDashesIndex);
7332
7354
  }
7333
- let parsed = mri2(argv, mriOptions);
7355
+ let parsed = lib_default(argv, mriOptions);
7334
7356
  parsed = Object.keys(parsed).reduce((res, name) => {
7335
- return __assign(__assign({}, res), {
7357
+ return {
7358
+ ...res,
7336
7359
  [camelcaseOptionName(name)]: parsed[name]
7337
- });
7360
+ };
7338
7361
  }, { _: [] });
7339
7362
  const args = parsed._;
7340
- const options = {
7341
- "--": argsAfterDoubleDashes
7342
- };
7363
+ const options = { "--": argsAfterDoubleDashes };
7343
7364
  const ignoreDefault = command && command.config.ignoreOptionDefaultValue ? command.config.ignoreOptionDefaultValue : this.globalCommand.config.ignoreOptionDefaultValue;
7344
- let transforms = Object.create(null);
7365
+ const transforms = Object.create(null);
7345
7366
  for (const cliOption of cliOptions) {
7346
- if (!ignoreDefault && cliOption.config.default !== undefined) {
7347
- for (const name of cliOption.names) {
7367
+ if (!ignoreDefault && cliOption.config.default !== undefined)
7368
+ for (const name of cliOption.names)
7348
7369
  options[name] = cliOption.config.default;
7349
- }
7350
- }
7351
- if (Array.isArray(cliOption.config.type)) {
7352
- if (transforms[cliOption.name] === undefined) {
7353
- transforms[cliOption.name] = Object.create(null);
7354
- transforms[cliOption.name]["shouldTransform"] = true;
7355
- transforms[cliOption.name]["transformFunction"] = cliOption.config.type[0];
7356
- }
7370
+ if (Array.isArray(cliOption.config.type) && transforms[cliOption.name] === undefined) {
7371
+ transforms[cliOption.name] = Object.create(null);
7372
+ transforms[cliOption.name].shouldTransform = true;
7373
+ transforms[cliOption.name].transformFunction = cliOption.config.type[0];
7357
7374
  }
7358
7375
  }
7359
- for (const key of Object.keys(parsed)) {
7376
+ for (const key of Object.keys(parsed))
7360
7377
  if (key !== "_") {
7361
- const keys = key.split(".");
7362
- setDotProp(options, keys, parsed[key]);
7378
+ setDotProp(options, key.split("."), parsed[key]);
7363
7379
  setByType(options, transforms);
7364
7380
  }
7365
- }
7366
7381
  return {
7367
7382
  args,
7368
7383
  options
@@ -7375,20 +7390,19 @@ class CAC extends EventEmitter {
7375
7390
  command.checkUnknownOptions();
7376
7391
  command.checkOptionValue();
7377
7392
  command.checkRequiredArgs();
7393
+ command.checkUnusedArgs();
7378
7394
  const actionArgs = [];
7379
7395
  command.args.forEach((arg, index) => {
7380
- if (arg.variadic) {
7396
+ if (arg.variadic)
7381
7397
  actionArgs.push(args.slice(index));
7382
- } else {
7398
+ else
7383
7399
  actionArgs.push(args[index]);
7384
- }
7385
7400
  });
7386
7401
  actionArgs.push(options);
7387
7402
  return command.commandAction.apply(this, actionArgs);
7388
7403
  }
7389
- }
7404
+ };
7390
7405
  var cac = (name = "") => new CAC(name);
7391
- var dist_default = cac;
7392
7406
 
7393
7407
  // src/index.ts
7394
7408
  var import_picocolors2 = __toESM(require_picocolors(), 1);
@@ -7546,7 +7560,8 @@ function formatNewVersion(originalConstraint, newVersion) {
7546
7560
  return `${startPart} - ${cleaned}`;
7547
7561
  }
7548
7562
  if (parsed.type === "range") {
7549
- return `^${cleaned}`;
7563
+ const updatedConstraint = originalConstraint.replace(/([><!=]+\s*)v?\d+(?:\.\d+)*(?:-[\w.]+)?/i, `$1${cleaned}`);
7564
+ return updatedConstraint || originalConstraint;
7550
7565
  }
7551
7566
  return `${parsed.prefix}${cleaned}`;
7552
7567
  }
@@ -7570,10 +7585,12 @@ function getCacheDir() {
7570
7585
  }
7571
7586
  return path.join(process.env.XDG_CACHE_HOME || path.join(home, ".cache"), "comze");
7572
7587
  }
7588
+ function getCacheFilePath(key) {
7589
+ return path.join(getCacheDir(), `${key}.json`);
7590
+ }
7573
7591
  async function getCacheEntry(key, expectedVersion) {
7574
7592
  try {
7575
- const cacheDir = getCacheDir();
7576
- const filePath = path.join(cacheDir, `${key}.json`);
7593
+ const filePath = getCacheFilePath(key);
7577
7594
  const content = await fs.readFile(filePath, "utf-8");
7578
7595
  const data = JSON.parse(content);
7579
7596
  if (data.version !== expectedVersion) {
@@ -7588,7 +7605,7 @@ async function setCache(key, value, version, meta = {}) {
7588
7605
  try {
7589
7606
  const cacheDir = getCacheDir();
7590
7607
  await fs.mkdir(cacheDir, { recursive: true });
7591
- const filePath = path.join(cacheDir, `${key}.json`);
7608
+ const filePath = getCacheFilePath(key);
7592
7609
  const data = {
7593
7610
  version,
7594
7611
  timestamp: Date.now(),
@@ -7603,10 +7620,8 @@ async function touchCache(key, version) {
7603
7620
  try {
7604
7621
  const entry = await getCacheEntry(key, version);
7605
7622
  if (entry) {
7606
- await setCache(key, entry.value, version, {
7607
- lastModified: entry.lastModified,
7608
- etag: entry.etag
7609
- });
7623
+ const now = new Date;
7624
+ await fs.utimes(getCacheFilePath(key), now, now);
7610
7625
  }
7611
7626
  } catch {}
7612
7627
  }
@@ -7707,6 +7722,9 @@ async function fetchPackage(packageName, minStability = "stable", preferStable =
7707
7722
  if (cachedEntry?.lastModified) {
7708
7723
  headers["If-Modified-Since"] = cachedEntry.lastModified;
7709
7724
  }
7725
+ if (cachedEntry?.etag) {
7726
+ headers["If-None-Match"] = cachedEntry.etag;
7727
+ }
7710
7728
  }
7711
7729
  let data;
7712
7730
  try {
@@ -7719,7 +7737,8 @@ async function fetchPackage(packageName, minStability = "stable", preferStable =
7719
7737
  data = await response.json();
7720
7738
  if (!noCache) {
7721
7739
  const lastModified = response.headers.get("Last-Modified") || undefined;
7722
- await setCache(cacheKey, data, CACHE_VERSION, { lastModified });
7740
+ const etag = response.headers.get("ETag") || undefined;
7741
+ await setCache(cacheKey, data, CACHE_VERSION, { lastModified, etag });
7723
7742
  }
7724
7743
  } else {
7725
7744
  return null;
@@ -7832,9 +7851,10 @@ async function fetchAllPackages(packages, minStability = "stable", preferStable
7832
7851
  }
7833
7852
 
7834
7853
  // src/writer.ts
7835
- import { readFile, writeFile } from "fs/promises";
7854
+ import { readFile, rename, rm, writeFile } from "fs/promises";
7836
7855
  import { existsSync } from "fs";
7837
7856
  import { spawn } from "child_process";
7857
+ import { basename, dirname, join } from "path";
7838
7858
 
7839
7859
  // node_modules/detect-indent/index.js
7840
7860
  var INDENT_REGEX = /^(?:( )+|\t+)/;
@@ -7974,12 +7994,17 @@ async function writeComposerJson(path2, updates, dryRun = false) {
7974
7994
  console.log("");
7975
7995
  return true;
7976
7996
  }
7997
+ const tempPath = join(dirname(path2), `.${basename(path2)}.${process.pid}.${Date.now()}.tmp`);
7977
7998
  try {
7978
7999
  const newContent = JSON.stringify(content, null, indent) + `
7979
8000
  `;
7980
- await writeFile(path2, newContent, "utf-8");
8001
+ await writeFile(tempPath, newContent, "utf-8");
8002
+ await rename(tempPath, path2);
7981
8003
  return true;
7982
8004
  } catch {
8005
+ try {
8006
+ await rm(tempPath, { force: true });
8007
+ } catch {}
7983
8008
  return false;
7984
8009
  }
7985
8010
  }
@@ -8184,10 +8209,40 @@ async function selectPackages(packages) {
8184
8209
  const selectedNames = new Set(response.selected);
8185
8210
  return packages.filter((pkg) => selectedNames.has(pkg.name));
8186
8211
  }
8212
+
8213
+ // src/config.ts
8214
+ function normalizeExcludeList(excludes) {
8215
+ return [...new Set(excludes.map((value) => value.trim().toLowerCase()).filter(Boolean))];
8216
+ }
8217
+ function getComposerExcludeList(composer) {
8218
+ const excludes = composer.extra?.comze?.exclude;
8219
+ if (!Array.isArray(excludes))
8220
+ return [];
8221
+ const validExcludes = excludes.filter((value) => typeof value === "string");
8222
+ return normalizeExcludeList(validExcludes);
8223
+ }
8224
+ function mergeExcludeLists(fileExcludes, cliExcludes) {
8225
+ return normalizeExcludeList([...fileExcludes, ...cliExcludes]);
8226
+ }
8227
+ function filterComposerPackages(allPackages, excludes) {
8228
+ const excludeSet = new Set(normalizeExcludeList(excludes));
8229
+ const filteredPackages = {};
8230
+ const ignoredPackages = [];
8231
+ for (const [name, version] of Object.entries(allPackages)) {
8232
+ if (name === "php" || name.startsWith("ext-"))
8233
+ continue;
8234
+ if (excludeSet.has(name.toLowerCase())) {
8235
+ ignoredPackages.push(name);
8236
+ continue;
8237
+ }
8238
+ filteredPackages[name] = version;
8239
+ }
8240
+ return { filteredPackages, ignoredPackages };
8241
+ }
8187
8242
  // package.json
8188
8243
  var package_default = {
8189
8244
  name: "comze",
8190
- version: "0.3.2",
8245
+ version: "0.4.0",
8191
8246
  description: "A taze-like CLI for updating composer.json dependencies",
8192
8247
  author: "qoqn",
8193
8248
  license: "MIT",
@@ -8226,14 +8281,14 @@ var package_default = {
8226
8281
  "@types/bun": "latest",
8227
8282
  "@types/prompts": "^2.4.9",
8228
8283
  "@types/semver": "^7.7.1",
8229
- typescript: "^5"
8284
+ typescript: "^6.0.2"
8230
8285
  },
8231
8286
  dependencies: {
8232
- cac: "^6.7.14",
8287
+ cac: "^7.0.0",
8233
8288
  "detect-indent": "^7.0.2",
8234
8289
  picocolors: "^1.1.1",
8235
8290
  prompts: "^2.4.2",
8236
- semver: "^7.7.3"
8291
+ semver: "^7.7.4"
8237
8292
  }
8238
8293
  };
8239
8294
 
@@ -8247,20 +8302,18 @@ async function run(options) {
8247
8302
  process.exit(1);
8248
8303
  }
8249
8304
  const minStability = composer.content["minimum-stability"] ?? "stable";
8250
- const preferStable = composer.content["prefer-stable"] ?? true;
8305
+ const preferStable = composer.content["prefer-stable"] === true;
8251
8306
  const allPackages = {
8252
8307
  ...composer.content.require,
8253
8308
  ...composer.content["require-dev"]
8254
8309
  };
8255
- const filteredPackages = {};
8256
- for (const [name, version] of Object.entries(allPackages)) {
8257
- if (name === "php" || name.startsWith("ext-"))
8258
- continue;
8259
- if (options.exclude.includes(name))
8260
- continue;
8261
- filteredPackages[name] = version;
8262
- }
8310
+ const fileExcludes = getComposerExcludeList(composer.content);
8311
+ const excludes = mergeExcludeLists(fileExcludes, options.exclude);
8312
+ const { filteredPackages, ignoredPackages } = filterComposerPackages(allPackages, excludes);
8263
8313
  console.log(import_picocolors2.default.gray(` Checking ${Object.keys(filteredPackages).length} packages...`));
8314
+ if (ignoredPackages.length > 0) {
8315
+ console.log(import_picocolors2.default.gray(` Ignoring ${ignoredPackages.length} package${ignoredPackages.length === 1 ? "" : "s"} from exclude list...`));
8316
+ }
8264
8317
  console.log(import_picocolors2.default.gray(` Stability: ${minStability}${preferStable ? " (prefer-stable)" : ""}
8265
8318
  `));
8266
8319
  const projectPhp = allPackages["php"];
@@ -8321,7 +8374,11 @@ async function run(options) {
8321
8374
  }
8322
8375
  if (options.write || options.install) {
8323
8376
  const success = await writeComposerJson(composerPath, selectedUpdates, options.dryRun);
8324
- if (success && !options.dryRun) {
8377
+ if (!success) {
8378
+ console.error(import_picocolors2.default.red(" ✗ Failed to update composer.json"));
8379
+ process.exit(1);
8380
+ }
8381
+ if (!options.dryRun) {
8325
8382
  console.log(import_picocolors2.default.green(" ✓ Updated composer.json"));
8326
8383
  if (options.write && !options.install) {
8327
8384
  console.log(import_picocolors2.default.gray(`
@@ -8353,10 +8410,10 @@ async function run(options) {
8353
8410
  }
8354
8411
 
8355
8412
  // src/cli.ts
8356
- var cli = dist_default("comze");
8413
+ var cli = cac("comze");
8357
8414
  cli.option("-w, --write", "Write changes to composer.json", { default: false }).option("-i, --install", "Write changes and run composer update", {
8358
8415
  default: false
8359
- }).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)", {
8416
+ }).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, merged with composer.json extra.comze.exclude)", {
8360
8417
  default: ""
8361
8418
  }).option("--dry-run", "Run without making changes", { default: false }).option("--no-cache", "Bypass cache and force fetch from network", { default: false });
8362
8419
  cli.help();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comze",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "A taze-like CLI for updating composer.json dependencies",
5
5
  "author": "qoqn",
6
6
  "license": "MIT",
@@ -39,13 +39,13 @@
39
39
  "@types/bun": "latest",
40
40
  "@types/prompts": "^2.4.9",
41
41
  "@types/semver": "^7.7.1",
42
- "typescript": "^5"
42
+ "typescript": "^6.0.2"
43
43
  },
44
44
  "dependencies": {
45
- "cac": "^6.7.14",
45
+ "cac": "^7.0.0",
46
46
  "detect-indent": "^7.0.2",
47
47
  "picocolors": "^1.1.1",
48
48
  "prompts": "^2.4.2",
49
- "semver": "^7.7.3"
49
+ "semver": "^7.7.4"
50
50
  }
51
51
  }