cargo-release.ts
1 #!/usr/bin/env -S deno run --allow-run 2 3 import { defineCommand, runMain } from "npm:citty"; 4 import { runSyncLoroVersion } from "./sync-loro-version.ts"; 5 6 async function runCargoRelease(version: string): Promise<string> { 7 const process = new Deno.Command("cargo", { 8 args: ["release", "version", "--workspace", version], 9 }); 10 const output = await process.output(); 11 return new TextDecoder().decode(output.stderr); 12 } 13 14 function parseNoChangesCrates(output: string): string[] { 15 const lines = output.split("\n"); 16 const noChangesCrates: string[] = []; 17 18 for (const line of lines) { 19 if (line.includes("despite no changes made since tag")) { 20 const match = line.match(/updating ([^ ]+) to/); 21 if (match) { 22 noChangesCrates.push(match[1]); 23 } 24 } 25 } 26 27 return noChangesCrates; 28 } 29 30 function generateOptimizedCommand( 31 version: string, 32 excludedCrates: string[], 33 ): string { 34 const excludeFlags = excludedCrates.map((crate) => `--exclude ${crate}`).join( 35 " ", 36 ); 37 return `cargo release version --workspace ${version} ${excludeFlags}`; 38 } 39 40 function isValidVersion(version: string): boolean { 41 // Matches format like 1.2.3 42 return /^\d+\.\d+\.\d+$/.test(version); 43 } 44 45 const main = defineCommand({ 46 meta: { 47 name: "cargo-release", 48 version: "1.0.0", 49 description: "Bump version with optimized excludes", 50 }, 51 args: { 52 version: { 53 type: "positional", 54 description: "Version to bump to (format: x.y.z)", 55 required: true, 56 }, 57 }, 58 async run({ args }) { 59 const version = args.version; 60 console.log(version); 61 62 if (!isValidVersion(version)) { 63 throw new Error("Version must be in format x.y.z (e.g., 1.2.3)"); 64 } 65 66 runSyncLoroVersion(version); 67 const output = await runCargoRelease(version); 68 console.log("Original output:"); 69 console.log(output); 70 71 const noChangesCrates = parseNoChangesCrates(output); 72 const excludeFlags = noChangesCrates.map((crate) => `--exclude ${crate}`).join( 73 " ", 74 ); 75 console.log("\n 1. Run command to bump version:"); 76 console.log(generateOptimizedCommand(version, noChangesCrates)); 77 console.log("2. Then Commit the changes"); 78 console.log("3. Run command to publish:"); 79 console.log( 80 `cargo release publish --workspace ${excludeFlags}`, 81 ); 82 console.log("4. Tag:"); 83 console.log( 84 `cargo release tag --workspace ${excludeFlags}`, 85 ); 86 console.log("5. Push:"); 87 console.log( 88 `git push --tags && git push`, 89 ); 90 }, 91 }); 92 93 runMain(main);