pubm 0.2.7 → 0.2.9
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/bin/cli.js +302 -114
- package/dist/index.cjs +435 -247
- package/dist/index.js +418 -230
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -4486,9 +4486,129 @@ var Listr = (_a23 = class {
|
|
|
4486
4486
|
// src/tasks/runner.ts
|
|
4487
4487
|
var import_semver3 = __toESM(require("semver"), 1);
|
|
4488
4488
|
var import_std_env = require("std-env");
|
|
4489
|
-
var
|
|
4489
|
+
var import_tinyexec9 = require("tinyexec");
|
|
4490
|
+
|
|
4491
|
+
// src/ecosystem/rust.ts
|
|
4492
|
+
var import_promises2 = require("fs/promises");
|
|
4493
|
+
var import_node_path2 = __toESM(require("path"), 1);
|
|
4494
|
+
var import_smol_toml = require("smol-toml");
|
|
4495
|
+
var import_tinyexec = require("tinyexec");
|
|
4496
|
+
|
|
4497
|
+
// src/ecosystem/ecosystem.ts
|
|
4498
|
+
var Ecosystem = class {
|
|
4499
|
+
constructor(packagePath) {
|
|
4500
|
+
this.packagePath = packagePath;
|
|
4501
|
+
}
|
|
4502
|
+
};
|
|
4503
|
+
|
|
4504
|
+
// src/ecosystem/rust.ts
|
|
4505
|
+
var RustEcosystem = class extends Ecosystem {
|
|
4506
|
+
static async detect(packagePath) {
|
|
4507
|
+
try {
|
|
4508
|
+
return (await (0, import_promises2.stat)(import_node_path2.default.join(packagePath, "Cargo.toml"))).isFile();
|
|
4509
|
+
} catch {
|
|
4510
|
+
return false;
|
|
4511
|
+
}
|
|
4512
|
+
}
|
|
4513
|
+
async readCargoToml() {
|
|
4514
|
+
const raw = await (0, import_promises2.readFile)(
|
|
4515
|
+
import_node_path2.default.join(this.packagePath, "Cargo.toml"),
|
|
4516
|
+
"utf-8"
|
|
4517
|
+
);
|
|
4518
|
+
return (0, import_smol_toml.parse)(raw);
|
|
4519
|
+
}
|
|
4520
|
+
async packageName() {
|
|
4521
|
+
const cargo = await this.readCargoToml();
|
|
4522
|
+
const pkg = cargo.package;
|
|
4523
|
+
return pkg.name;
|
|
4524
|
+
}
|
|
4525
|
+
async readVersion() {
|
|
4526
|
+
const cargo = await this.readCargoToml();
|
|
4527
|
+
const pkg = cargo.package;
|
|
4528
|
+
return pkg.version;
|
|
4529
|
+
}
|
|
4530
|
+
async writeVersion(newVersion) {
|
|
4531
|
+
const filePath = import_node_path2.default.join(this.packagePath, "Cargo.toml");
|
|
4532
|
+
const raw = await (0, import_promises2.readFile)(filePath, "utf-8");
|
|
4533
|
+
const cargo = (0, import_smol_toml.parse)(raw);
|
|
4534
|
+
const pkg = cargo.package;
|
|
4535
|
+
pkg.version = newVersion;
|
|
4536
|
+
await (0, import_promises2.writeFile)(filePath, (0, import_smol_toml.stringify)(cargo));
|
|
4537
|
+
}
|
|
4538
|
+
/**
|
|
4539
|
+
* Update the `version` field of dependencies that match sibling crate names.
|
|
4540
|
+
* This ensures `cargo publish` works when crates depend on each other via path.
|
|
4541
|
+
*/
|
|
4542
|
+
async updateSiblingDependencyVersions(siblingVersions) {
|
|
4543
|
+
const filePath = import_node_path2.default.join(this.packagePath, "Cargo.toml");
|
|
4544
|
+
const raw = await (0, import_promises2.readFile)(filePath, "utf-8");
|
|
4545
|
+
const cargo = (0, import_smol_toml.parse)(raw);
|
|
4546
|
+
let modified = false;
|
|
4547
|
+
for (const section of ["dependencies", "build-dependencies"]) {
|
|
4548
|
+
const sectionData = cargo[section];
|
|
4549
|
+
if (!sectionData) continue;
|
|
4550
|
+
for (const [depName, depValue] of Object.entries(sectionData)) {
|
|
4551
|
+
if (typeof depValue === "object" && depValue !== null && "path" in depValue && siblingVersions.has(depName)) {
|
|
4552
|
+
const dep = depValue;
|
|
4553
|
+
dep.version = siblingVersions.get(depName);
|
|
4554
|
+
modified = true;
|
|
4555
|
+
}
|
|
4556
|
+
}
|
|
4557
|
+
}
|
|
4558
|
+
if (modified) {
|
|
4559
|
+
await (0, import_promises2.writeFile)(filePath, (0, import_smol_toml.stringify)(cargo));
|
|
4560
|
+
}
|
|
4561
|
+
return modified;
|
|
4562
|
+
}
|
|
4563
|
+
async syncLockfile() {
|
|
4564
|
+
const lockfilePath = await this.findLockfile();
|
|
4565
|
+
if (!lockfilePath) return void 0;
|
|
4566
|
+
const name = await this.packageName();
|
|
4567
|
+
await (0, import_tinyexec.exec)("cargo", ["update", "--package", name], {
|
|
4568
|
+
nodeOptions: { cwd: import_node_path2.default.dirname(lockfilePath) }
|
|
4569
|
+
});
|
|
4570
|
+
return lockfilePath;
|
|
4571
|
+
}
|
|
4572
|
+
async findLockfile() {
|
|
4573
|
+
let dir = this.packagePath;
|
|
4574
|
+
const { root } = import_node_path2.default.parse(dir);
|
|
4575
|
+
while (dir !== root) {
|
|
4576
|
+
const candidate = import_node_path2.default.join(dir, "Cargo.lock");
|
|
4577
|
+
try {
|
|
4578
|
+
if ((await (0, import_promises2.stat)(candidate)).isFile()) return candidate;
|
|
4579
|
+
} catch {
|
|
4580
|
+
}
|
|
4581
|
+
dir = import_node_path2.default.dirname(dir);
|
|
4582
|
+
}
|
|
4583
|
+
return void 0;
|
|
4584
|
+
}
|
|
4585
|
+
async dependencies() {
|
|
4586
|
+
const cargo = await this.readCargoToml();
|
|
4587
|
+
const deps = [];
|
|
4588
|
+
for (const section of ["dependencies", "build-dependencies"]) {
|
|
4589
|
+
const sectionData = cargo[section];
|
|
4590
|
+
if (sectionData) {
|
|
4591
|
+
deps.push(...Object.keys(sectionData));
|
|
4592
|
+
}
|
|
4593
|
+
}
|
|
4594
|
+
return deps;
|
|
4595
|
+
}
|
|
4596
|
+
manifestFiles() {
|
|
4597
|
+
return ["Cargo.toml"];
|
|
4598
|
+
}
|
|
4599
|
+
defaultTestCommand() {
|
|
4600
|
+
return "cargo test";
|
|
4601
|
+
}
|
|
4602
|
+
defaultBuildCommand() {
|
|
4603
|
+
return "cargo build --release";
|
|
4604
|
+
}
|
|
4605
|
+
supportedRegistries() {
|
|
4606
|
+
return ["crates"];
|
|
4607
|
+
}
|
|
4608
|
+
};
|
|
4490
4609
|
|
|
4491
4610
|
// src/error.ts
|
|
4611
|
+
var import_tinyexec2 = require("tinyexec");
|
|
4492
4612
|
var AbstractError = class extends Error {
|
|
4493
4613
|
constructor(message, { cause } = {}) {
|
|
4494
4614
|
super(message, { cause });
|
|
@@ -4499,20 +4619,49 @@ var AbstractError = class extends Error {
|
|
|
4499
4619
|
function replaceCode(code) {
|
|
4500
4620
|
return code.replace(/`([^`].+)`/g, color.bold(color.underline("$1")));
|
|
4501
4621
|
}
|
|
4622
|
+
function formatStderr(stderr) {
|
|
4623
|
+
return stderr.split("\n").map((line) => ` ${color.dim("\u2502")} ${line}`).join("\n");
|
|
4624
|
+
}
|
|
4625
|
+
function isNoisyCause(cause) {
|
|
4626
|
+
if (cause instanceof import_tinyexec2.NonZeroExitError) return true;
|
|
4627
|
+
if (cause instanceof Error && /Process exited with non-zero status/i.test(cause.message))
|
|
4628
|
+
return true;
|
|
4629
|
+
return false;
|
|
4630
|
+
}
|
|
4502
4631
|
function formatError(error) {
|
|
4503
4632
|
if (!(error instanceof Error)) return `${error}`;
|
|
4504
|
-
const
|
|
4633
|
+
const rawMessage = typeof error.message === "string" ? error.message : (
|
|
4505
4634
|
/* v8 ignore next */
|
|
4506
|
-
|
|
4635
|
+
String(error)
|
|
4507
4636
|
);
|
|
4508
|
-
|
|
4637
|
+
const newlineIndex = rawMessage.indexOf("\n");
|
|
4638
|
+
let summary;
|
|
4639
|
+
let detail;
|
|
4640
|
+
if (newlineIndex !== -1) {
|
|
4641
|
+
summary = rawMessage.slice(0, newlineIndex);
|
|
4642
|
+
detail = rawMessage.slice(newlineIndex + 1);
|
|
4643
|
+
} else {
|
|
4644
|
+
summary = rawMessage;
|
|
4645
|
+
}
|
|
4646
|
+
let result = `${color.bgRed(` ${error.name} `)}${color.reset("")} ${replaceCode(summary)}
|
|
4647
|
+
`;
|
|
4648
|
+
if (detail) {
|
|
4649
|
+
result += `
|
|
4650
|
+
${formatStderr(detail)}
|
|
4509
4651
|
`;
|
|
4510
|
-
stringifyError += error.stack?.split("\n").slice(1).join("\n").replace(/at/g, color.dim("at")).replace(/\(([^(].+)\)/g, `(${color.blue("$1")})`);
|
|
4511
|
-
if (error.cause) {
|
|
4512
|
-
stringifyError += "\n\nCaused: ";
|
|
4513
|
-
stringifyError += formatError(error.cause);
|
|
4514
4652
|
}
|
|
4515
|
-
|
|
4653
|
+
if (process.env.DEBUG === "pubm" && error.stack) {
|
|
4654
|
+
result += error.stack.split("\n").slice(1).join("\n").replace(/at/g, color.dim("at")).replace(/\(([^(].+)\)/g, `(${color.blue("$1")})`);
|
|
4655
|
+
}
|
|
4656
|
+
if (error.cause && !isNoisyCause(error.cause)) {
|
|
4657
|
+
const causeMsg = error.cause instanceof Error ? error.cause.message : String(error.cause);
|
|
4658
|
+
if (causeMsg !== summary) {
|
|
4659
|
+
result += `
|
|
4660
|
+
${color.dim("Caused by:")} `;
|
|
4661
|
+
result += formatError(error.cause);
|
|
4662
|
+
}
|
|
4663
|
+
}
|
|
4664
|
+
return result;
|
|
4516
4665
|
}
|
|
4517
4666
|
function consoleError(error) {
|
|
4518
4667
|
let errorText = "\n";
|
|
@@ -4529,7 +4678,7 @@ function consoleError(error) {
|
|
|
4529
4678
|
|
|
4530
4679
|
// src/git.ts
|
|
4531
4680
|
var import_semver = __toESM(require("semver"), 1);
|
|
4532
|
-
var
|
|
4681
|
+
var import_tinyexec3 = require("tinyexec");
|
|
4533
4682
|
var GitError = class extends AbstractError {
|
|
4534
4683
|
constructor() {
|
|
4535
4684
|
super(...arguments);
|
|
@@ -4538,7 +4687,7 @@ var GitError = class extends AbstractError {
|
|
|
4538
4687
|
};
|
|
4539
4688
|
var Git = class {
|
|
4540
4689
|
async git(args) {
|
|
4541
|
-
const { stdout } = await (0,
|
|
4690
|
+
const { stdout } = await (0, import_tinyexec3.exec)("git", args, { throwOnError: true });
|
|
4542
4691
|
return stdout;
|
|
4543
4692
|
}
|
|
4544
4693
|
async userName() {
|
|
@@ -4792,7 +4941,7 @@ var Git = class {
|
|
|
4792
4941
|
async push(options) {
|
|
4793
4942
|
const args = ["push", options].filter((v) => v);
|
|
4794
4943
|
try {
|
|
4795
|
-
const { stderr } = await (0,
|
|
4944
|
+
const { stderr } = await (0, import_tinyexec3.exec)("git", args, { throwOnError: true });
|
|
4796
4945
|
if (`${stderr}`.includes("GH006")) {
|
|
4797
4946
|
return false;
|
|
4798
4947
|
}
|
|
@@ -4814,125 +4963,6 @@ function link2(text, url) {
|
|
|
4814
4963
|
return `\x1B]8;;${url}\x07${text}\x1B]8;;\x07`;
|
|
4815
4964
|
}
|
|
4816
4965
|
|
|
4817
|
-
// src/ecosystem/rust.ts
|
|
4818
|
-
var import_promises2 = require("fs/promises");
|
|
4819
|
-
var import_node_path2 = __toESM(require("path"), 1);
|
|
4820
|
-
var import_smol_toml = require("smol-toml");
|
|
4821
|
-
var import_tinyexec2 = require("tinyexec");
|
|
4822
|
-
|
|
4823
|
-
// src/ecosystem/ecosystem.ts
|
|
4824
|
-
var Ecosystem = class {
|
|
4825
|
-
constructor(packagePath) {
|
|
4826
|
-
this.packagePath = packagePath;
|
|
4827
|
-
}
|
|
4828
|
-
};
|
|
4829
|
-
|
|
4830
|
-
// src/ecosystem/rust.ts
|
|
4831
|
-
var RustEcosystem = class extends Ecosystem {
|
|
4832
|
-
static async detect(packagePath) {
|
|
4833
|
-
try {
|
|
4834
|
-
return (await (0, import_promises2.stat)(import_node_path2.default.join(packagePath, "Cargo.toml"))).isFile();
|
|
4835
|
-
} catch {
|
|
4836
|
-
return false;
|
|
4837
|
-
}
|
|
4838
|
-
}
|
|
4839
|
-
async readCargoToml() {
|
|
4840
|
-
const raw = await (0, import_promises2.readFile)(
|
|
4841
|
-
import_node_path2.default.join(this.packagePath, "Cargo.toml"),
|
|
4842
|
-
"utf-8"
|
|
4843
|
-
);
|
|
4844
|
-
return (0, import_smol_toml.parse)(raw);
|
|
4845
|
-
}
|
|
4846
|
-
async packageName() {
|
|
4847
|
-
const cargo = await this.readCargoToml();
|
|
4848
|
-
const pkg = cargo.package;
|
|
4849
|
-
return pkg.name;
|
|
4850
|
-
}
|
|
4851
|
-
async readVersion() {
|
|
4852
|
-
const cargo = await this.readCargoToml();
|
|
4853
|
-
const pkg = cargo.package;
|
|
4854
|
-
return pkg.version;
|
|
4855
|
-
}
|
|
4856
|
-
async writeVersion(newVersion) {
|
|
4857
|
-
const filePath = import_node_path2.default.join(this.packagePath, "Cargo.toml");
|
|
4858
|
-
const raw = await (0, import_promises2.readFile)(filePath, "utf-8");
|
|
4859
|
-
const cargo = (0, import_smol_toml.parse)(raw);
|
|
4860
|
-
const pkg = cargo.package;
|
|
4861
|
-
pkg.version = newVersion;
|
|
4862
|
-
await (0, import_promises2.writeFile)(filePath, (0, import_smol_toml.stringify)(cargo));
|
|
4863
|
-
}
|
|
4864
|
-
/**
|
|
4865
|
-
* Update the `version` field of dependencies that match sibling crate names.
|
|
4866
|
-
* This ensures `cargo publish` works when crates depend on each other via path.
|
|
4867
|
-
*/
|
|
4868
|
-
async updateSiblingDependencyVersions(siblingVersions) {
|
|
4869
|
-
const filePath = import_node_path2.default.join(this.packagePath, "Cargo.toml");
|
|
4870
|
-
const raw = await (0, import_promises2.readFile)(filePath, "utf-8");
|
|
4871
|
-
const cargo = (0, import_smol_toml.parse)(raw);
|
|
4872
|
-
let modified = false;
|
|
4873
|
-
for (const section of ["dependencies", "build-dependencies"]) {
|
|
4874
|
-
const sectionData = cargo[section];
|
|
4875
|
-
if (!sectionData) continue;
|
|
4876
|
-
for (const [depName, depValue] of Object.entries(sectionData)) {
|
|
4877
|
-
if (typeof depValue === "object" && depValue !== null && "path" in depValue && siblingVersions.has(depName)) {
|
|
4878
|
-
const dep = depValue;
|
|
4879
|
-
dep.version = siblingVersions.get(depName);
|
|
4880
|
-
modified = true;
|
|
4881
|
-
}
|
|
4882
|
-
}
|
|
4883
|
-
}
|
|
4884
|
-
if (modified) {
|
|
4885
|
-
await (0, import_promises2.writeFile)(filePath, (0, import_smol_toml.stringify)(cargo));
|
|
4886
|
-
}
|
|
4887
|
-
return modified;
|
|
4888
|
-
}
|
|
4889
|
-
async syncLockfile() {
|
|
4890
|
-
const lockfilePath = await this.findLockfile();
|
|
4891
|
-
if (!lockfilePath) return void 0;
|
|
4892
|
-
const name = await this.packageName();
|
|
4893
|
-
await (0, import_tinyexec2.exec)("cargo", ["update", "--package", name], {
|
|
4894
|
-
nodeOptions: { cwd: import_node_path2.default.dirname(lockfilePath) }
|
|
4895
|
-
});
|
|
4896
|
-
return lockfilePath;
|
|
4897
|
-
}
|
|
4898
|
-
async findLockfile() {
|
|
4899
|
-
let dir = this.packagePath;
|
|
4900
|
-
const { root } = import_node_path2.default.parse(dir);
|
|
4901
|
-
while (dir !== root) {
|
|
4902
|
-
const candidate = import_node_path2.default.join(dir, "Cargo.lock");
|
|
4903
|
-
try {
|
|
4904
|
-
if ((await (0, import_promises2.stat)(candidate)).isFile()) return candidate;
|
|
4905
|
-
} catch {
|
|
4906
|
-
}
|
|
4907
|
-
dir = import_node_path2.default.dirname(dir);
|
|
4908
|
-
}
|
|
4909
|
-
return void 0;
|
|
4910
|
-
}
|
|
4911
|
-
async dependencies() {
|
|
4912
|
-
const cargo = await this.readCargoToml();
|
|
4913
|
-
const deps = [];
|
|
4914
|
-
for (const section of ["dependencies", "build-dependencies"]) {
|
|
4915
|
-
const sectionData = cargo[section];
|
|
4916
|
-
if (sectionData) {
|
|
4917
|
-
deps.push(...Object.keys(sectionData));
|
|
4918
|
-
}
|
|
4919
|
-
}
|
|
4920
|
-
return deps;
|
|
4921
|
-
}
|
|
4922
|
-
manifestFiles() {
|
|
4923
|
-
return ["Cargo.toml"];
|
|
4924
|
-
}
|
|
4925
|
-
defaultTestCommand() {
|
|
4926
|
-
return "cargo test";
|
|
4927
|
-
}
|
|
4928
|
-
defaultBuildCommand() {
|
|
4929
|
-
return "cargo build --release";
|
|
4930
|
-
}
|
|
4931
|
-
supportedRegistries() {
|
|
4932
|
-
return ["crates"];
|
|
4933
|
-
}
|
|
4934
|
-
};
|
|
4935
|
-
|
|
4936
4966
|
// src/utils/crate-graph.ts
|
|
4937
4967
|
async function sortCratesByDependencyOrder(cratePaths) {
|
|
4938
4968
|
if (cratePaths.length <= 1) return cratePaths;
|
|
@@ -4985,12 +5015,19 @@ var rollbacks = [];
|
|
|
4985
5015
|
function addRollback(rollback2, context) {
|
|
4986
5016
|
rollbacks.push({ fn: rollback2, ctx: context });
|
|
4987
5017
|
}
|
|
5018
|
+
function rollbackLog(message) {
|
|
5019
|
+
console.log(` ${color.yellow("\u21A9")} ${message}`);
|
|
5020
|
+
}
|
|
5021
|
+
function rollbackError(message) {
|
|
5022
|
+
console.error(` ${color.red("\u2717")} ${message}`);
|
|
5023
|
+
}
|
|
4988
5024
|
var called = false;
|
|
4989
5025
|
async function rollback() {
|
|
4990
5026
|
if (called) return void 0;
|
|
4991
5027
|
called = true;
|
|
4992
5028
|
if (rollbacks.length <= 0) return void 0;
|
|
4993
|
-
console.log(
|
|
5029
|
+
console.log(`
|
|
5030
|
+
${color.yellow("\u27F2")} ${color.yellow("Rolling back...")}`);
|
|
4994
5031
|
const results = await Promise.allSettled(
|
|
4995
5032
|
rollbacks.map(({ fn, ctx }) => fn(ctx))
|
|
4996
5033
|
);
|
|
@@ -4999,15 +5036,15 @@ async function rollback() {
|
|
|
4999
5036
|
);
|
|
5000
5037
|
if (failures.length > 0) {
|
|
5001
5038
|
for (const failure of failures) {
|
|
5002
|
-
|
|
5003
|
-
|
|
5039
|
+
rollbackError(
|
|
5040
|
+
failure.reason instanceof Error ? failure.reason.message : failure.reason
|
|
5004
5041
|
);
|
|
5005
5042
|
}
|
|
5006
5043
|
console.log(
|
|
5007
|
-
"Rollback completed with errors. Some operations may require manual recovery
|
|
5044
|
+
`${color.red("\u2717")} ${color.red("Rollback completed with errors.")} Some operations may require manual recovery.`
|
|
5008
5045
|
);
|
|
5009
5046
|
} else {
|
|
5010
|
-
console.log("Rollback completed
|
|
5047
|
+
console.log(`${color.green("\u2713")} Rollback completed`);
|
|
5011
5048
|
}
|
|
5012
5049
|
}
|
|
5013
5050
|
|
|
@@ -5415,7 +5452,7 @@ function injectTokensToEnv(tokens) {
|
|
|
5415
5452
|
|
|
5416
5453
|
// src/registry/crates.ts
|
|
5417
5454
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
5418
|
-
var
|
|
5455
|
+
var import_tinyexec4 = require("tinyexec");
|
|
5419
5456
|
|
|
5420
5457
|
// src/registry/registry.ts
|
|
5421
5458
|
var Registry = class {
|
|
@@ -5435,6 +5472,14 @@ var CratesError = class extends AbstractError {
|
|
|
5435
5472
|
}
|
|
5436
5473
|
};
|
|
5437
5474
|
var USER_AGENT = "pubm (https://github.com/syi0808/pubm)";
|
|
5475
|
+
function cleanCargoStderr(stderr) {
|
|
5476
|
+
return stderr.split("\n").filter((line) => {
|
|
5477
|
+
const trimmed = line.trim();
|
|
5478
|
+
if (trimmed === "Updating crates.io index") return false;
|
|
5479
|
+
if (trimmed === "") return false;
|
|
5480
|
+
return true;
|
|
5481
|
+
}).join("\n");
|
|
5482
|
+
}
|
|
5438
5483
|
var CratesRegistry = class extends Registry {
|
|
5439
5484
|
constructor() {
|
|
5440
5485
|
super(...arguments);
|
|
@@ -5455,7 +5500,7 @@ var CratesRegistry = class extends Registry {
|
|
|
5455
5500
|
}
|
|
5456
5501
|
async isInstalled() {
|
|
5457
5502
|
try {
|
|
5458
|
-
await (0,
|
|
5503
|
+
await (0, import_tinyexec4.exec)("cargo", ["--version"]);
|
|
5459
5504
|
return true;
|
|
5460
5505
|
} catch {
|
|
5461
5506
|
return false;
|
|
@@ -5496,29 +5541,43 @@ var CratesRegistry = class extends Registry {
|
|
|
5496
5541
|
if (manifestDir) {
|
|
5497
5542
|
args.push("--manifest-path", import_node_path5.default.join(manifestDir, "Cargo.toml"));
|
|
5498
5543
|
}
|
|
5499
|
-
await (0,
|
|
5544
|
+
await (0, import_tinyexec4.exec)("cargo", args, { throwOnError: true });
|
|
5500
5545
|
return true;
|
|
5501
5546
|
} catch (error) {
|
|
5502
|
-
const stderr = error instanceof
|
|
5547
|
+
const stderr = error instanceof import_tinyexec4.NonZeroExitError ? error.output?.stderr : void 0;
|
|
5503
5548
|
const message = stderr ? `Failed to run \`cargo publish\`:
|
|
5504
|
-
${stderr}` : "Failed to run `cargo publish`";
|
|
5549
|
+
${cleanCargoStderr(stderr)}` : "Failed to run `cargo publish`";
|
|
5505
5550
|
throw new CratesError(message, { cause: error });
|
|
5506
5551
|
}
|
|
5507
5552
|
}
|
|
5508
5553
|
async dryRunPublish(manifestDir) {
|
|
5509
5554
|
try {
|
|
5510
|
-
const args = ["publish", "--dry-run"
|
|
5555
|
+
const args = ["publish", "--dry-run"];
|
|
5511
5556
|
if (manifestDir) {
|
|
5512
5557
|
args.push("--manifest-path", import_node_path5.default.join(manifestDir, "Cargo.toml"));
|
|
5513
5558
|
}
|
|
5514
|
-
await (0,
|
|
5559
|
+
await (0, import_tinyexec4.exec)("cargo", args, { throwOnError: true });
|
|
5515
5560
|
} catch (error) {
|
|
5516
|
-
const stderr = error instanceof
|
|
5561
|
+
const stderr = error instanceof import_tinyexec4.NonZeroExitError ? error.output?.stderr : void 0;
|
|
5517
5562
|
const message = stderr ? `Failed to run \`cargo publish --dry-run\`:
|
|
5518
|
-
${stderr}` : "Failed to run `cargo publish --dry-run`";
|
|
5563
|
+
${cleanCargoStderr(stderr)}` : "Failed to run `cargo publish --dry-run`";
|
|
5519
5564
|
throw new CratesError(message, { cause: error });
|
|
5520
5565
|
}
|
|
5521
5566
|
}
|
|
5567
|
+
async isVersionPublished(version2) {
|
|
5568
|
+
try {
|
|
5569
|
+
const response = await fetch(
|
|
5570
|
+
`${this.registry}/api/v1/crates/${this.packageName}/${version2}`,
|
|
5571
|
+
{ headers: this.headers }
|
|
5572
|
+
);
|
|
5573
|
+
return response.ok;
|
|
5574
|
+
} catch (error) {
|
|
5575
|
+
throw new CratesError(
|
|
5576
|
+
`Failed to check version ${version2} for '${this.packageName}' on crates.io`,
|
|
5577
|
+
{ cause: error }
|
|
5578
|
+
);
|
|
5579
|
+
}
|
|
5580
|
+
}
|
|
5522
5581
|
async isPublished() {
|
|
5523
5582
|
try {
|
|
5524
5583
|
const response = await fetch(
|
|
@@ -5595,10 +5654,24 @@ function createCratesPublishTask(packagePath) {
|
|
|
5595
5654
|
const label = packagePath ? ` (${packagePath})` : "";
|
|
5596
5655
|
return {
|
|
5597
5656
|
title: `Publishing to crates.io${label}`,
|
|
5598
|
-
task: async () => {
|
|
5657
|
+
task: async (ctx, task) => {
|
|
5599
5658
|
const packageName = await getCrateName(packagePath);
|
|
5600
5659
|
const registry = new CratesRegistry(packageName);
|
|
5601
|
-
await registry.
|
|
5660
|
+
if (await registry.isVersionPublished(ctx.version)) {
|
|
5661
|
+
task.title = `[SKIPPED] crates.io${label}: v${ctx.version} already published`;
|
|
5662
|
+
task.output = `\u26A0 ${packageName}@${ctx.version} is already published on crates.io`;
|
|
5663
|
+
return task.skip();
|
|
5664
|
+
}
|
|
5665
|
+
try {
|
|
5666
|
+
await registry.publish(packagePath);
|
|
5667
|
+
} catch (error) {
|
|
5668
|
+
if (error instanceof Error && error.message.includes("is already uploaded")) {
|
|
5669
|
+
task.title = `[SKIPPED] crates.io${label}: v${ctx.version} already published`;
|
|
5670
|
+
task.output = `\u26A0 ${packageName}@${ctx.version} is already published on crates.io`;
|
|
5671
|
+
return task.skip();
|
|
5672
|
+
}
|
|
5673
|
+
throw error;
|
|
5674
|
+
}
|
|
5602
5675
|
}
|
|
5603
5676
|
};
|
|
5604
5677
|
}
|
|
@@ -5609,7 +5682,7 @@ var cratesPublishTasks = createCratesPublishTask();
|
|
|
5609
5682
|
var import_prompt_adapter_enquirer = require("@listr2/prompt-adapter-enquirer");
|
|
5610
5683
|
|
|
5611
5684
|
// src/registry/jsr.ts
|
|
5612
|
-
var
|
|
5685
|
+
var import_tinyexec5 = require("tinyexec");
|
|
5613
5686
|
|
|
5614
5687
|
// src/utils/package-name.ts
|
|
5615
5688
|
var import_node_module = require("module");
|
|
@@ -5677,7 +5750,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5677
5750
|
this.client = new JsrClient(getApiEndpoint(this.registry));
|
|
5678
5751
|
}
|
|
5679
5752
|
async jsr(args) {
|
|
5680
|
-
const { stdout } = await (0,
|
|
5753
|
+
const { stdout } = await (0, import_tinyexec5.exec)("jsr", args, { throwOnError: true });
|
|
5681
5754
|
return stdout;
|
|
5682
5755
|
}
|
|
5683
5756
|
async isInstalled() {
|
|
@@ -5693,7 +5766,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5693
5766
|
}
|
|
5694
5767
|
async ping() {
|
|
5695
5768
|
try {
|
|
5696
|
-
const { stdout } = await (0,
|
|
5769
|
+
const { stdout } = await (0, import_tinyexec5.exec)(
|
|
5697
5770
|
"ping",
|
|
5698
5771
|
[new URL(this.registry).hostname, "-c", "1"],
|
|
5699
5772
|
{ throwOnError: true }
|
|
@@ -5708,7 +5781,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5708
5781
|
}
|
|
5709
5782
|
async publish() {
|
|
5710
5783
|
try {
|
|
5711
|
-
await (0,
|
|
5784
|
+
await (0, import_tinyexec5.exec)(
|
|
5712
5785
|
"jsr",
|
|
5713
5786
|
["publish", "--allow-dirty", "--token", `${JsrClient.token}`],
|
|
5714
5787
|
{
|
|
@@ -5718,7 +5791,7 @@ var JsrRegisry = class extends Registry {
|
|
|
5718
5791
|
this.packageCreationUrls = void 0;
|
|
5719
5792
|
return true;
|
|
5720
5793
|
} catch (error) {
|
|
5721
|
-
const stderr = error instanceof
|
|
5794
|
+
const stderr = error instanceof import_tinyexec5.NonZeroExitError ? error.output?.stderr : void 0;
|
|
5722
5795
|
if (stderr?.includes("don't exist")) {
|
|
5723
5796
|
const urls = [...stderr.matchAll(/https:\/\/jsr\.io\/new\S+/g)].map(
|
|
5724
5797
|
(m) => m[0]
|
|
@@ -5739,7 +5812,7 @@ ${stderr}` : ""}`,
|
|
|
5739
5812
|
}
|
|
5740
5813
|
async dryRunPublish() {
|
|
5741
5814
|
try {
|
|
5742
|
-
await (0,
|
|
5815
|
+
await (0, import_tinyexec5.exec)(
|
|
5743
5816
|
"jsr",
|
|
5744
5817
|
[
|
|
5745
5818
|
"publish",
|
|
@@ -5770,6 +5843,20 @@ ${stderr}` : ""}`,
|
|
|
5770
5843
|
);
|
|
5771
5844
|
}
|
|
5772
5845
|
}
|
|
5846
|
+
async isVersionPublished(version2) {
|
|
5847
|
+
try {
|
|
5848
|
+
const [scope, name] = getScopeAndName(this.packageName);
|
|
5849
|
+
const response = await fetch(
|
|
5850
|
+
`${this.registry}/@${scope}/${name}/${version2}`
|
|
5851
|
+
);
|
|
5852
|
+
return response.status === 200;
|
|
5853
|
+
} catch (error) {
|
|
5854
|
+
throw new JsrError(
|
|
5855
|
+
`Failed to fetch \`${this.registry}/${this.packageName}/${version2}\``,
|
|
5856
|
+
{ cause: error }
|
|
5857
|
+
);
|
|
5858
|
+
}
|
|
5859
|
+
}
|
|
5773
5860
|
async hasPermission() {
|
|
5774
5861
|
return this.client.scopePermission(`${getScope(this.packageName)}`) !== null;
|
|
5775
5862
|
}
|
|
@@ -5999,7 +6086,7 @@ async function jsrRegistry() {
|
|
|
5999
6086
|
// src/registry/npm.ts
|
|
6000
6087
|
var import_node_os = require("os");
|
|
6001
6088
|
var import_node_path6 = require("path");
|
|
6002
|
-
var
|
|
6089
|
+
var import_tinyexec6 = require("tinyexec");
|
|
6003
6090
|
var NpmError = class extends AbstractError {
|
|
6004
6091
|
constructor() {
|
|
6005
6092
|
super(...arguments);
|
|
@@ -6012,7 +6099,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6012
6099
|
__publicField(this, "registry", "https://registry.npmjs.org");
|
|
6013
6100
|
}
|
|
6014
6101
|
async npm(args) {
|
|
6015
|
-
const { stdout } = await (0,
|
|
6102
|
+
const { stdout } = await (0, import_tinyexec6.exec)("npm", args, { throwOnError: true });
|
|
6016
6103
|
return stdout;
|
|
6017
6104
|
}
|
|
6018
6105
|
async isInstalled() {
|
|
@@ -6044,6 +6131,19 @@ var NpmRegistry = class extends Registry {
|
|
|
6044
6131
|
);
|
|
6045
6132
|
}
|
|
6046
6133
|
}
|
|
6134
|
+
async isVersionPublished(version2) {
|
|
6135
|
+
try {
|
|
6136
|
+
const response = await fetch(
|
|
6137
|
+
`${this.registry}/${this.packageName}/${version2}`
|
|
6138
|
+
);
|
|
6139
|
+
return response.status === 200;
|
|
6140
|
+
} catch (error) {
|
|
6141
|
+
throw new NpmError(
|
|
6142
|
+
`Failed to fetch \`${this.registry}/${this.packageName}/${version2}\``,
|
|
6143
|
+
{ cause: error }
|
|
6144
|
+
);
|
|
6145
|
+
}
|
|
6146
|
+
}
|
|
6047
6147
|
async userName() {
|
|
6048
6148
|
try {
|
|
6049
6149
|
return (await this.npm(["whoami"])).trim();
|
|
@@ -6056,7 +6156,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6056
6156
|
await this.npm(["whoami"]);
|
|
6057
6157
|
return true;
|
|
6058
6158
|
} catch (error) {
|
|
6059
|
-
if (error instanceof
|
|
6159
|
+
if (error instanceof import_tinyexec6.NonZeroExitError) {
|
|
6060
6160
|
return false;
|
|
6061
6161
|
}
|
|
6062
6162
|
throw new NpmError("Failed to run `npm whoami`", { cause: error });
|
|
@@ -6123,7 +6223,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6123
6223
|
}
|
|
6124
6224
|
async ping() {
|
|
6125
6225
|
try {
|
|
6126
|
-
await (0,
|
|
6226
|
+
await (0, import_tinyexec6.exec)("npm", ["ping"], { throwOnError: true });
|
|
6127
6227
|
return true;
|
|
6128
6228
|
} catch (error) {
|
|
6129
6229
|
throw new NpmError("Failed to run `npm ping`", { cause: error });
|
|
@@ -6134,7 +6234,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6134
6234
|
await this.npm(["publish", "--provenance", "--access", "public"]);
|
|
6135
6235
|
return true;
|
|
6136
6236
|
} catch (error) {
|
|
6137
|
-
if (error instanceof
|
|
6237
|
+
if (error instanceof import_tinyexec6.NonZeroExitError && error.output?.stderr.includes("EOTP")) {
|
|
6138
6238
|
return false;
|
|
6139
6239
|
}
|
|
6140
6240
|
throw this.classifyPublishError(error);
|
|
@@ -6146,7 +6246,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6146
6246
|
await this.npm(args);
|
|
6147
6247
|
return true;
|
|
6148
6248
|
} catch (error) {
|
|
6149
|
-
if (error instanceof
|
|
6249
|
+
if (error instanceof import_tinyexec6.NonZeroExitError && error.output?.stderr.includes("EOTP")) {
|
|
6150
6250
|
return false;
|
|
6151
6251
|
}
|
|
6152
6252
|
throw this.classifyPublishError(error);
|
|
@@ -6154,7 +6254,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6154
6254
|
}
|
|
6155
6255
|
async dryRunPublish() {
|
|
6156
6256
|
try {
|
|
6157
|
-
await (0,
|
|
6257
|
+
await (0, import_tinyexec6.exec)("npm", ["publish", "--dry-run"], {
|
|
6158
6258
|
throwOnError: true,
|
|
6159
6259
|
nodeOptions: {
|
|
6160
6260
|
env: {
|
|
@@ -6164,7 +6264,7 @@ var NpmRegistry = class extends Registry {
|
|
|
6164
6264
|
}
|
|
6165
6265
|
});
|
|
6166
6266
|
} catch (error) {
|
|
6167
|
-
const stderr = error instanceof
|
|
6267
|
+
const stderr = error instanceof import_tinyexec6.NonZeroExitError ? error.output?.stderr : void 0;
|
|
6168
6268
|
throw new NpmError(
|
|
6169
6269
|
`Failed to run \`npm publish --dry-run\`${stderr ? `
|
|
6170
6270
|
${stderr}` : ""}`,
|
|
@@ -6191,7 +6291,7 @@ ${stderr}` : ""}`,
|
|
|
6191
6291
|
};
|
|
6192
6292
|
}
|
|
6193
6293
|
classifyPublishError(error) {
|
|
6194
|
-
if (error instanceof
|
|
6294
|
+
if (error instanceof import_tinyexec6.NonZeroExitError) {
|
|
6195
6295
|
const stderr = error.output?.stderr ?? "";
|
|
6196
6296
|
if (stderr.includes("EOTP")) {
|
|
6197
6297
|
return new NpmError("OTP required for publishing", { cause: error });
|
|
@@ -6249,20 +6349,30 @@ async function withTokenRetry(registryKey, task, action) {
|
|
|
6249
6349
|
}
|
|
6250
6350
|
var npmDryRunPublishTask = {
|
|
6251
6351
|
title: "Dry-run npm publish",
|
|
6252
|
-
task: async (
|
|
6352
|
+
task: async (ctx, task) => {
|
|
6353
|
+
const npm = await npmRegistry();
|
|
6354
|
+
if (await npm.isVersionPublished(ctx.version)) {
|
|
6355
|
+
task.title = `[SKIPPED] Dry-run npm publish: v${ctx.version} already published`;
|
|
6356
|
+
task.output = `\u26A0 ${npm.packageName}@${ctx.version} is already published on npm`;
|
|
6357
|
+
return task.skip();
|
|
6358
|
+
}
|
|
6253
6359
|
task.output = "Running npm publish --dry-run...";
|
|
6254
6360
|
await withTokenRetry("npm", task, async () => {
|
|
6255
|
-
const npm = await npmRegistry();
|
|
6256
6361
|
await npm.dryRunPublish();
|
|
6257
6362
|
});
|
|
6258
6363
|
}
|
|
6259
6364
|
};
|
|
6260
6365
|
var jsrDryRunPublishTask = {
|
|
6261
6366
|
title: "Dry-run jsr publish",
|
|
6262
|
-
task: async (
|
|
6367
|
+
task: async (ctx, task) => {
|
|
6368
|
+
const jsr = await jsrRegistry();
|
|
6369
|
+
if (await jsr.isVersionPublished(ctx.version)) {
|
|
6370
|
+
task.title = `[SKIPPED] Dry-run jsr publish: v${ctx.version} already published`;
|
|
6371
|
+
task.output = `\u26A0 ${jsr.packageName}@${ctx.version} is already published on jsr`;
|
|
6372
|
+
return task.skip();
|
|
6373
|
+
}
|
|
6263
6374
|
task.output = "Running jsr publish --dry-run...";
|
|
6264
6375
|
await withTokenRetry("jsr", task, async () => {
|
|
6265
|
-
const jsr = await jsrRegistry();
|
|
6266
6376
|
await jsr.dryRunPublish();
|
|
6267
6377
|
});
|
|
6268
6378
|
}
|
|
@@ -6271,17 +6381,58 @@ async function getCrateName2(packagePath) {
|
|
|
6271
6381
|
const eco = new RustEcosystem(packagePath ?? process.cwd());
|
|
6272
6382
|
return await eco.packageName();
|
|
6273
6383
|
}
|
|
6274
|
-
|
|
6384
|
+
var MISSING_CRATE_PATTERN = /no matching package named `([^`]+)` found/;
|
|
6385
|
+
async function findUnpublishedSiblingDeps(packagePath, siblingCrateNames) {
|
|
6386
|
+
const eco = new RustEcosystem(packagePath ?? process.cwd());
|
|
6387
|
+
const deps = await eco.dependencies();
|
|
6388
|
+
const siblingDeps = deps.filter((d2) => siblingCrateNames.includes(d2));
|
|
6389
|
+
const results = await Promise.all(
|
|
6390
|
+
siblingDeps.map(async (name) => {
|
|
6391
|
+
const registry = new CratesRegistry(name);
|
|
6392
|
+
const published = await registry.isPublished();
|
|
6393
|
+
return published ? null : name;
|
|
6394
|
+
})
|
|
6395
|
+
);
|
|
6396
|
+
return results.filter((name) => name !== null);
|
|
6397
|
+
}
|
|
6398
|
+
function createCratesDryRunPublishTask(packagePath, siblingCrateNames) {
|
|
6275
6399
|
const label = packagePath ? ` (${packagePath})` : "";
|
|
6276
6400
|
return {
|
|
6277
6401
|
title: `Dry-run crates.io publish${label}`,
|
|
6278
|
-
task: async (
|
|
6402
|
+
task: async (ctx, task) => {
|
|
6403
|
+
const packageName = await getCrateName2(packagePath);
|
|
6404
|
+
const registry = new CratesRegistry(packageName);
|
|
6405
|
+
if (await registry.isVersionPublished(ctx.version)) {
|
|
6406
|
+
task.title = `[SKIPPED] Dry-run crates.io publish${label}: v${ctx.version} already published`;
|
|
6407
|
+
task.output = `\u26A0 ${packageName}@${ctx.version} is already published on crates.io`;
|
|
6408
|
+
return task.skip();
|
|
6409
|
+
}
|
|
6410
|
+
if (siblingCrateNames?.length) {
|
|
6411
|
+
const unpublished = await findUnpublishedSiblingDeps(
|
|
6412
|
+
packagePath,
|
|
6413
|
+
siblingCrateNames
|
|
6414
|
+
);
|
|
6415
|
+
if (unpublished.length > 0) {
|
|
6416
|
+
task.title = `Dry-run crates.io publish${label} [skipped: sibling crate \`${unpublished.join("`, `")}\` not yet published]`;
|
|
6417
|
+
return;
|
|
6418
|
+
}
|
|
6419
|
+
}
|
|
6279
6420
|
task.output = "Running cargo publish --dry-run...";
|
|
6280
|
-
|
|
6281
|
-
|
|
6282
|
-
|
|
6283
|
-
|
|
6284
|
-
|
|
6421
|
+
try {
|
|
6422
|
+
await withTokenRetry("crates", task, async () => {
|
|
6423
|
+
const packageName2 = await getCrateName2(packagePath);
|
|
6424
|
+
const registry2 = new CratesRegistry(packageName2);
|
|
6425
|
+
await registry2.dryRunPublish(packagePath);
|
|
6426
|
+
});
|
|
6427
|
+
} catch (error) {
|
|
6428
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
6429
|
+
const match = message.match(MISSING_CRATE_PATTERN);
|
|
6430
|
+
if (match && siblingCrateNames?.includes(match[1])) {
|
|
6431
|
+
task.title = `Dry-run crates.io publish${label} [skipped: sibling crate \`${match[1]}\` not yet published]`;
|
|
6432
|
+
return;
|
|
6433
|
+
}
|
|
6434
|
+
throw error;
|
|
6435
|
+
}
|
|
6285
6436
|
}
|
|
6286
6437
|
};
|
|
6287
6438
|
}
|
|
@@ -6462,48 +6613,62 @@ var jsrPublishTasks = {
|
|
|
6462
6613
|
title: "Running jsr publish",
|
|
6463
6614
|
task: async (ctx, task) => {
|
|
6464
6615
|
const jsr = await jsrRegistry();
|
|
6616
|
+
if (await jsr.isVersionPublished(ctx.version)) {
|
|
6617
|
+
task.title = `[SKIPPED] jsr: v${ctx.version} already published`;
|
|
6618
|
+
task.output = `\u26A0 ${jsr.packageName}@${ctx.version} is already published on jsr`;
|
|
6619
|
+
return task.skip();
|
|
6620
|
+
}
|
|
6465
6621
|
task.output = "Publishing on jsr...";
|
|
6466
|
-
|
|
6467
|
-
|
|
6468
|
-
|
|
6469
|
-
|
|
6470
|
-
|
|
6471
|
-
|
|
6622
|
+
try {
|
|
6623
|
+
if (!JsrClient.token && !ctx.promptEnabled) {
|
|
6624
|
+
const jsrTokenEnv = import_node_process6.default.env.JSR_TOKEN;
|
|
6625
|
+
if (!jsrTokenEnv) {
|
|
6626
|
+
throw new JsrAvailableError(
|
|
6627
|
+
"JSR_TOKEN not found in the environment variables. Please set the token and try again."
|
|
6628
|
+
);
|
|
6629
|
+
}
|
|
6630
|
+
JsrClient.token = jsrTokenEnv;
|
|
6472
6631
|
}
|
|
6473
|
-
|
|
6474
|
-
|
|
6475
|
-
|
|
6476
|
-
|
|
6477
|
-
|
|
6478
|
-
|
|
6479
|
-
|
|
6480
|
-
const maxAttempts = 3;
|
|
6481
|
-
task.output = `Package doesn't exist on jsr. Create it at:
|
|
6632
|
+
let result = await jsr.publish();
|
|
6633
|
+
if (!result && jsr.packageCreationUrls) {
|
|
6634
|
+
if (ctx.promptEnabled) {
|
|
6635
|
+
task.title = "Running jsr publish (package creation needed)";
|
|
6636
|
+
const urls = jsr.packageCreationUrls;
|
|
6637
|
+
const maxAttempts = 3;
|
|
6638
|
+
task.output = `Package doesn't exist on jsr. Create it at:
|
|
6482
6639
|
${urls.map((url) => ` ${color.cyan(url)}`).join("\n")}`;
|
|
6483
|
-
|
|
6484
|
-
|
|
6485
|
-
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
|
|
6489
|
-
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6640
|
+
open(urls[0]);
|
|
6641
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
6642
|
+
await task.prompt(import_prompt_adapter_enquirer2.ListrEnquirerPromptAdapter).run({
|
|
6643
|
+
type: "input",
|
|
6644
|
+
message: `Press ${color.bold("enter")} after creating the package on jsr.io${attempt > 1 ? ` (attempt ${attempt}/${maxAttempts})` : ""}`
|
|
6645
|
+
});
|
|
6646
|
+
result = await jsr.publish();
|
|
6647
|
+
if (result) break;
|
|
6648
|
+
if (attempt < maxAttempts) {
|
|
6649
|
+
task.output = "Package still doesn't exist. Please create it and try again.";
|
|
6650
|
+
}
|
|
6493
6651
|
}
|
|
6494
|
-
|
|
6495
|
-
|
|
6652
|
+
if (!result) {
|
|
6653
|
+
throw new JsrAvailableError(
|
|
6654
|
+
"Package creation not completed after 3 attempts."
|
|
6655
|
+
);
|
|
6656
|
+
}
|
|
6657
|
+
task.title = "Running jsr publish (package created)";
|
|
6658
|
+
} else {
|
|
6496
6659
|
throw new JsrAvailableError(
|
|
6497
|
-
|
|
6660
|
+
`Package doesn't exist on jsr. Create it at:
|
|
6661
|
+
${jsr.packageCreationUrls.join("\n")}`
|
|
6498
6662
|
);
|
|
6499
6663
|
}
|
|
6500
|
-
task.title = "Running jsr publish (package created)";
|
|
6501
|
-
} else {
|
|
6502
|
-
throw new JsrAvailableError(
|
|
6503
|
-
`Package doesn't exist on jsr. Create it at:
|
|
6504
|
-
${jsr.packageCreationUrls.join("\n")}`
|
|
6505
|
-
);
|
|
6506
6664
|
}
|
|
6665
|
+
} catch (error) {
|
|
6666
|
+
if (error instanceof Error && error.message.includes("already published")) {
|
|
6667
|
+
task.title = `[SKIPPED] jsr: v${ctx.version} already published`;
|
|
6668
|
+
task.output = `\u26A0 ${jsr.packageName}@${ctx.version} is already published on jsr`;
|
|
6669
|
+
return task.skip();
|
|
6670
|
+
}
|
|
6671
|
+
throw error;
|
|
6507
6672
|
}
|
|
6508
6673
|
}
|
|
6509
6674
|
};
|
|
@@ -6600,44 +6765,62 @@ var npmPublishTasks = {
|
|
|
6600
6765
|
skip: (ctx) => !!ctx.preview,
|
|
6601
6766
|
task: async (ctx, task) => {
|
|
6602
6767
|
const npm = await npmRegistry();
|
|
6768
|
+
if (await npm.isVersionPublished(ctx.version)) {
|
|
6769
|
+
task.title = `[SKIPPED] npm: v${ctx.version} already published`;
|
|
6770
|
+
task.output = `\u26A0 ${npm.packageName}@${ctx.version} is already published on npm`;
|
|
6771
|
+
return task.skip();
|
|
6772
|
+
}
|
|
6603
6773
|
task.output = "Publishing on npm...";
|
|
6604
|
-
|
|
6605
|
-
|
|
6606
|
-
|
|
6607
|
-
|
|
6608
|
-
|
|
6609
|
-
|
|
6610
|
-
|
|
6611
|
-
await
|
|
6612
|
-
|
|
6613
|
-
|
|
6614
|
-
|
|
6615
|
-
|
|
6616
|
-
|
|
6617
|
-
|
|
6618
|
-
|
|
6774
|
+
try {
|
|
6775
|
+
if (ctx.promptEnabled) {
|
|
6776
|
+
let result = await npm.publish();
|
|
6777
|
+
if (!result) {
|
|
6778
|
+
task.title = "Running npm publish (OTP code needed)";
|
|
6779
|
+
const maxAttempts = 3;
|
|
6780
|
+
for (let attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
6781
|
+
result = await npm.publish(
|
|
6782
|
+
await task.prompt(import_prompt_adapter_enquirer3.ListrEnquirerPromptAdapter).run({
|
|
6783
|
+
type: "password",
|
|
6784
|
+
message: `npm OTP code${attempt > 1 ? ` (attempt ${attempt}/${maxAttempts})` : ""}`
|
|
6785
|
+
})
|
|
6786
|
+
);
|
|
6787
|
+
if (result) break;
|
|
6788
|
+
if (attempt < maxAttempts) {
|
|
6789
|
+
task.output = "2FA failed. Please try again.";
|
|
6790
|
+
}
|
|
6791
|
+
}
|
|
6792
|
+
if (!result) {
|
|
6793
|
+
throw new NpmAvailableError(
|
|
6794
|
+
"OTP verification failed after 3 attempts."
|
|
6795
|
+
);
|
|
6619
6796
|
}
|
|
6797
|
+
task.title = "Running npm publish (2FA passed)";
|
|
6798
|
+
}
|
|
6799
|
+
} else {
|
|
6800
|
+
const npmTokenEnv = import_node_process7.default.env.NODE_AUTH_TOKEN;
|
|
6801
|
+
if (!npmTokenEnv) {
|
|
6802
|
+
throw new NpmAvailableError(
|
|
6803
|
+
"NODE_AUTH_TOKEN not found in environment variables. Set it in your CI configuration:\n GitHub Actions: Add NODE_AUTH_TOKEN as a repository secret\n Other CI: Export NODE_AUTH_TOKEN with your npm access token"
|
|
6804
|
+
);
|
|
6620
6805
|
}
|
|
6806
|
+
const result = await npm.publishProvenance();
|
|
6621
6807
|
if (!result) {
|
|
6622
6808
|
throw new NpmAvailableError(
|
|
6623
|
-
|
|
6809
|
+
`In CI environment, publishing with 2FA is not allowed. Please disable 2FA when accessing with a token from https://www.npmjs.com/package/${npm.packageName}/access `
|
|
6624
6810
|
);
|
|
6625
6811
|
}
|
|
6626
|
-
task.title = "Running npm publish (2FA passed)";
|
|
6627
|
-
}
|
|
6628
|
-
} else {
|
|
6629
|
-
const npmTokenEnv = import_node_process7.default.env.NODE_AUTH_TOKEN;
|
|
6630
|
-
if (!npmTokenEnv) {
|
|
6631
|
-
throw new NpmAvailableError(
|
|
6632
|
-
"NODE_AUTH_TOKEN not found in environment variables. Set it in your CI configuration:\n GitHub Actions: Add NODE_AUTH_TOKEN as a repository secret\n Other CI: Export NODE_AUTH_TOKEN with your npm access token"
|
|
6633
|
-
);
|
|
6634
6812
|
}
|
|
6635
|
-
|
|
6636
|
-
if (
|
|
6637
|
-
|
|
6638
|
-
|
|
6639
|
-
|
|
6813
|
+
} catch (error) {
|
|
6814
|
+
if (error instanceof Error && (error.message.includes(
|
|
6815
|
+
"cannot publish over the previously published"
|
|
6816
|
+
) || error.message.includes(
|
|
6817
|
+
"You cannot publish over the previously published"
|
|
6818
|
+
))) {
|
|
6819
|
+
task.title = `[SKIPPED] npm: v${ctx.version} already published`;
|
|
6820
|
+
task.output = `\u26A0 ${npm.packageName}@${ctx.version} is already published on npm`;
|
|
6821
|
+
return task.skip();
|
|
6640
6822
|
}
|
|
6823
|
+
throw error;
|
|
6641
6824
|
}
|
|
6642
6825
|
}
|
|
6643
6826
|
};
|
|
@@ -6645,7 +6828,7 @@ var npmPublishTasks = {
|
|
|
6645
6828
|
// src/tasks/preflight.ts
|
|
6646
6829
|
var import_node_crypto2 = require("crypto");
|
|
6647
6830
|
var import_prompt_adapter_enquirer4 = require("@listr2/prompt-adapter-enquirer");
|
|
6648
|
-
var
|
|
6831
|
+
var import_tinyexec7 = require("tinyexec");
|
|
6649
6832
|
var PreflightError = class extends AbstractError {
|
|
6650
6833
|
constructor() {
|
|
6651
6834
|
super(...arguments);
|
|
@@ -6672,7 +6855,7 @@ async function syncGhSecrets(tokens) {
|
|
|
6672
6855
|
for (const [registry, token] of Object.entries(tokens)) {
|
|
6673
6856
|
const config = TOKEN_CONFIG[registry];
|
|
6674
6857
|
if (!config) continue;
|
|
6675
|
-
const result = (0,
|
|
6858
|
+
const result = (0, import_tinyexec7.exec)("gh", ["secret", "set", config.ghSecretName], {
|
|
6676
6859
|
throwOnError: true
|
|
6677
6860
|
});
|
|
6678
6861
|
const proc = result.process;
|
|
@@ -6866,10 +7049,10 @@ var prerequisitesCheckTask = (options) => {
|
|
|
6866
7049
|
var import_prompt_adapter_enquirer6 = require("@listr2/prompt-adapter-enquirer");
|
|
6867
7050
|
|
|
6868
7051
|
// src/registry/custom-registry.ts
|
|
6869
|
-
var
|
|
7052
|
+
var import_tinyexec8 = require("tinyexec");
|
|
6870
7053
|
var CustomRegistry = class extends NpmRegistry {
|
|
6871
7054
|
async npm(args) {
|
|
6872
|
-
const { stdout } = await (0,
|
|
7055
|
+
const { stdout } = await (0, import_tinyexec8.exec)(
|
|
6873
7056
|
"npm",
|
|
6874
7057
|
args.concat("--registry", this.registry),
|
|
6875
7058
|
{ throwOnError: true }
|
|
@@ -7128,10 +7311,15 @@ async function collectDryRunPublishTasks(ctx) {
|
|
|
7128
7311
|
return nonCratesTasks;
|
|
7129
7312
|
}
|
|
7130
7313
|
const sortedPaths = await sortCratesByDependencyOrder(cratesPaths);
|
|
7314
|
+
const siblingCrateNames = await Promise.all(
|
|
7315
|
+
cratesPaths.map((p) => new RustEcosystem(p).packageName())
|
|
7316
|
+
);
|
|
7131
7317
|
const sequentialCratesTask = {
|
|
7132
7318
|
title: "Dry-run crates.io publish (sequential)",
|
|
7133
7319
|
task: (_ctx, task) => task.newListr(
|
|
7134
|
-
sortedPaths.map(
|
|
7320
|
+
sortedPaths.map(
|
|
7321
|
+
(p) => createCratesDryRunPublishTask(p, siblingCrateNames)
|
|
7322
|
+
),
|
|
7135
7323
|
{ concurrent: false }
|
|
7136
7324
|
)
|
|
7137
7325
|
};
|
|
@@ -7186,7 +7374,7 @@ async function run(options) {
|
|
|
7186
7374
|
task: async (ctx2) => {
|
|
7187
7375
|
const packageManager = await getPackageManager();
|
|
7188
7376
|
try {
|
|
7189
|
-
await (0,
|
|
7377
|
+
await (0, import_tinyexec9.exec)(packageManager, ["run", ctx2.testScript], {
|
|
7190
7378
|
throwOnError: true
|
|
7191
7379
|
});
|
|
7192
7380
|
} catch (error) {
|
|
@@ -7203,7 +7391,7 @@ async function run(options) {
|
|
|
7203
7391
|
task: async (ctx2) => {
|
|
7204
7392
|
const packageManager = await getPackageManager();
|
|
7205
7393
|
try {
|
|
7206
|
-
await (0,
|
|
7394
|
+
await (0, import_tinyexec9.exec)(packageManager, ["run", ctx2.buildScript], {
|
|
7207
7395
|
throwOnError: true
|
|
7208
7396
|
});
|
|
7209
7397
|
} catch (error) {
|
|
@@ -7224,23 +7412,23 @@ async function run(options) {
|
|
|
7224
7412
|
addRollback(async () => {
|
|
7225
7413
|
if (tagCreated) {
|
|
7226
7414
|
try {
|
|
7227
|
-
|
|
7415
|
+
rollbackLog("Deleting tag");
|
|
7228
7416
|
await git.deleteTag(`${await git.latestTag()}`);
|
|
7229
7417
|
} catch (error) {
|
|
7230
|
-
|
|
7418
|
+
rollbackError(
|
|
7231
7419
|
`Failed to delete tag: ${error instanceof Error ? error.message : error}`
|
|
7232
7420
|
);
|
|
7233
7421
|
}
|
|
7234
7422
|
}
|
|
7235
7423
|
if (commited) {
|
|
7236
7424
|
try {
|
|
7237
|
-
|
|
7425
|
+
rollbackLog("Resetting commits");
|
|
7238
7426
|
await git.reset();
|
|
7239
7427
|
await git.stash();
|
|
7240
7428
|
await git.reset("HEAD^", "--hard");
|
|
7241
7429
|
await git.popStash();
|
|
7242
7430
|
} catch (error) {
|
|
7243
|
-
|
|
7431
|
+
rollbackError(
|
|
7244
7432
|
`Failed to reset commits: ${error instanceof Error ? error.message : error}`
|
|
7245
7433
|
);
|
|
7246
7434
|
}
|