@storm-software/workspace-tools
Version:
Tools for managing a Storm workspace, including various Nx generators and executors for common development tasks.
214 lines (211 loc) • 8.13 kB
JavaScript
import {
getCrateRegistryVersion
} from "./chunk-EGI64HQ2.mjs";
import {
parseCargoToml,
parseCargoTomlWithTree,
stringifyCargoToml
} from "./chunk-GEN563U4.mjs";
import {
getWorkspaceConfig
} from "./chunk-4PKTZSV2.mjs";
// src/release/rust-version-actions.ts
import {
joinPathFragments
} from "@nx/devkit";
import { VersionActions } from "nx/release";
var StormRustVersionActions = class extends VersionActions {
validManifestFilenames = ["Cargo.toml"];
/**
* The Storm workspace configuration object, which is loaded from the `storm-workspace.json` file.
*
* @remarks
* This member variable is populated during the {@link init} method.
*/
workspaceConfig = null;
constructor(releaseGroup, projectGraphNode, finalConfigForProject) {
super(releaseGroup, projectGraphNode, finalConfigForProject);
}
/**
* Asynchronous initialization of the version actions and resolution of manifest paths.
*
* @remarks
* This does NOT validate that manifest files exist - that happens later in validate().
*
* @params tree - The file system tree to read from.
*/
async init(tree) {
this.workspaceConfig = await getWorkspaceConfig();
return super.init(tree);
}
async readCurrentVersionFromSourceManifest(tree) {
const sourceCargoTomlPath = joinPathFragments(
this.projectGraphNode.data.root,
"Cargo.toml"
);
try {
const cargoToml = parseCargoTomlWithTree(
tree,
this.projectGraphNode.data.root,
this.projectGraphNode.name
);
return {
manifestPath: sourceCargoTomlPath,
currentVersion: cargoToml.package.version
};
} catch {
throw new Error(
`Unable to determine the current version for project "${this.projectGraphNode.name}" from ${sourceCargoTomlPath}, please ensure that the "version" field is set within the Cargo.toml file`
);
}
}
async readCurrentVersionFromRegistry(tree, currentVersionResolverMetadata) {
const cargoToml = parseCargoTomlWithTree(
tree,
this.projectGraphNode.data.root,
this.projectGraphNode.name
);
const crateName = cargoToml.package.name;
const metadata = currentVersionResolverMetadata;
const registryArg = typeof metadata?.registry === "string" ? metadata.registry : this.workspaceConfig?.registry?.cargo || "https://crates.io";
const tagArg = typeof metadata?.tag === "string" ? metadata.tag : "latest";
let currentVersion = null;
try {
currentVersion = await getCrateRegistryVersion(
crateName,
tagArg,
registryArg
);
} catch {
}
return {
currentVersion: currentVersion || "0.0.0",
// Make troubleshooting easier by including the registry and tag data in the log text
logText: `"cargoRegistry=${registryArg}" tag=${tagArg}`
};
}
async readCurrentVersionOfDependency(tree, projectGraph, dependencyProjectName) {
const cargoToml = parseCargoTomlWithTree(
tree,
this.projectGraphNode.data.root,
this.projectGraphNode.name
);
if (!projectGraph.nodes[dependencyProjectName]?.data?.root) {
return {
currentVersion: null,
dependencyCollection: null
};
}
const dependencyCargoToml = parseCargoTomlWithTree(
tree,
projectGraph.nodes[dependencyProjectName]?.data.root,
dependencyProjectName
);
if (!dependencyCargoToml?.package?.name) {
return {
currentVersion: null,
dependencyCollection: null
};
}
let currentVersion = null;
let dependencyCollection = null;
for (const depType of ["dependencies", "dev-dependencies"]) {
if (cargoToml[depType] && cargoToml[depType][dependencyCargoToml.package.name]) {
currentVersion = typeof cargoToml[depType][dependencyCargoToml.package.name] === "string" ? cargoToml[depType][dependencyCargoToml.package.name] : cargoToml[depType][dependencyCargoToml.package.name].version;
dependencyCollection = depType;
break;
}
}
return {
currentVersion,
dependencyCollection
};
}
async updateProjectVersion(tree, newVersion) {
const logMessages = [];
for (const manifestToUpdate of this.manifestsToUpdate) {
const cargoTomlString = tree.read(manifestToUpdate.manifestPath)?.toString();
if (!cargoTomlString) {
throw new Error(
`Unable to read Cargo.toml at path: ${manifestToUpdate.manifestPath}`
);
}
const cargoToml = parseCargoToml(cargoTomlString);
cargoToml.package.version = newVersion;
tree.write(manifestToUpdate.manifestPath, stringifyCargoToml(cargoToml));
logMessages.push(
`\u270D\uFE0F New version ${newVersion} written to manifest: ${manifestToUpdate.manifestPath}`
);
}
return logMessages;
}
/**
* Updates the dependencies of the project in the specified Cargo.toml files.
*
* @param tree - The file system tree to read from and write to.
* @param projectGraph - The project graph to use for resolving dependencies.
* @param dependenciesToUpdate - A mapping of dependency names to their new versions.
* @returns An array of log messages indicating the results of the updates.
*/
async updateProjectDependencies(tree, projectGraph, dependenciesToUpdate = {}) {
const numDependenciesToUpdate = Object.keys(dependenciesToUpdate).length;
if (numDependenciesToUpdate === 0) {
return [];
}
const logMessages = [];
for (const manifestToUpdate of this.manifestsToUpdate) {
const cargoTomlString = tree.read(manifestToUpdate.manifestPath)?.toString();
if (!cargoTomlString) {
throw new Error(
`Unable to read Cargo.toml at path: ${manifestToUpdate.manifestPath}`
);
}
const cargoToml = parseCargoToml(cargoTomlString);
for (const depType of ["dependencies", "dev-dependencies"]) {
if (cargoToml[depType]) {
for (const [dep, version] of Object.entries(dependenciesToUpdate)) {
try {
const projectRoot = projectGraph.nodes[dep]?.data.root;
if (!projectRoot) {
throw new Error(
`Unable to determine the project root for "${dep}" from the project graph metadata, please ensure that the "@storm-software/workspace-tools" plugin is installed and the project graph has been built. If the issue persists, please report this issue on https://github.com/storm-software/storm-ops/issues`
);
}
const dependencyCargoTomlString = tree.read(manifestToUpdate.manifestPath)?.toString();
if (!dependencyCargoTomlString) {
throw new Error(
`Unable to read Cargo.toml at path: ${manifestToUpdate.manifestPath}`
);
}
const dependencyCargoToml = parseCargoToml(
dependencyCargoTomlString
);
const dependencyCrateName = cargoToml[depType][dependencyCargoToml.package.name] ? dependencyCargoToml.package.name : dep;
if (typeof cargoToml[depType][dependencyCrateName] === "string") {
cargoToml[depType][dependencyCrateName] = version;
} else {
cargoToml[depType][dependencyCrateName].version = version;
}
tree.write(
manifestToUpdate.manifestPath,
stringifyCargoToml(cargoToml)
);
} catch (error) {
throw new Error(
`Unable to update ${depType === "dev-dependencies" ? "dev-dependency" : "dependency"} "${dep}" in manifest at path: ${manifestToUpdate.manifestPath}.`,
{ cause: error }
);
}
}
}
}
logMessages.push(
`\u270D\uFE0F Updated ${numDependenciesToUpdate} ${numDependenciesToUpdate === 1 ? "dependency" : "dependencies"} in manifest: ${manifestToUpdate.manifestPath}`
);
}
return logMessages;
}
};
export {
StormRustVersionActions
};