UNPKG

@storm-software/workspace-tools

Version:

Tools for managing a Storm workspace, including various Nx generators and executors for common development tasks.

724 lines (713 loc) • 32.4 kB
import { modifyCargoTable, parseCargoToml, parseCargoTomlWithTree, stringifyCargoToml } from "./chunk-7ENGREV2.mjs"; import { getConfig, getStopwatch, writeDebug, writeError, writeFatal, writeInfo, writeSuccess, writeTrace } from "./chunk-NODM27UV.mjs"; import { findWorkspaceRoot } from "./chunk-FR3YQN55.mjs"; import { __name } from "./chunk-2BPV2XV2.mjs"; // src/generators/release-version/generator.ts import { formatFiles, joinPathFragments, output, readJson, updateJson, writeJson } from "@nx/devkit"; import { resolveLocalPackageDependencies as resolveLocalPackageJsonDependencies } from "@nx/js/src/generators/release-version/utils/resolve-local-package-dependencies"; import { updateLockFile } from "@nx/js/src/generators/release-version/utils/update-lock-file"; // ../git-tools/src/types.ts var DEFAULT_COMMIT_TYPES = { /* --- Bumps version when selected --- */ chore: { description: "Other changes that don't modify src or test files", title: "Chore", emoji: "\u2699\uFE0F ", semverBump: "patch", changelog: { title: "Miscellaneous", hidden: false } }, fix: { description: "A change that resolves an issue previously identified with the package", title: "Bug Fix", emoji: "\u{1FAB2} ", semverBump: "patch", changelog: { title: "Bug Fixes", hidden: false } }, feat: { description: "A change that adds a new feature to the package", title: "Feature", emoji: "\u{1F511} ", semverBump: "minor", changelog: { title: "Features", hidden: false } }, ci: { description: "Changes to our CI configuration files and scripts (example scopes: Travis, Circle, BrowserStack, SauceLabs)", title: "Continuous Integration", emoji: "\u{1F9F0} ", semverBump: "patch", changelog: { title: "Continuous Integration", hidden: false } }, refactor: { description: "A code change that neither fixes a bug nor adds a feature", title: "Code Refactoring", emoji: "\u{1F9EA} ", semverBump: "patch", changelog: { title: "Source Code Improvements", hidden: false } }, style: { description: "Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)", title: "Style Improvements", emoji: "\u{1F48E} ", semverBump: "patch", changelog: { title: "Style Improvements", hidden: false } }, perf: { description: "A code change that improves performance", title: "Performance Improvement", emoji: "\u23F1\uFE0F ", semverBump: "patch", changelog: { title: "Performance Improvements", hidden: false } }, /* --- Does not bump version when selected --- */ docs: { description: "A change that only includes documentation updates", title: "Documentation", emoji: "\u{1F4DC} ", semverBump: "none", changelog: { title: "Documentation", hidden: false } }, test: { description: "Adding missing tests or correcting existing tests", title: "Testing", emoji: "\u{1F6A8} ", semverBump: "none", changelog: { title: "Testing", hidden: true } }, /* --- Not included in commitlint but included in changelog --- */ deps: { description: "Changes that add, update, or remove dependencies. This includes devDependencies and peerDependencies", title: "Dependencies", emoji: "\u{1F4E6} ", hidden: true, semverBump: "patch", changelog: { title: "Dependency Upgrades", hidden: false } }, /* --- Not included in commitlint or changelog --- */ build: { description: "Changes that affect the build system or external dependencies (example scopes: gulp, broccoli, npm)", title: "Build", emoji: "\u{1F6E0} ", hidden: true, semverBump: "none", changelog: { title: "Build", hidden: true } }, release: { description: "Publishing a commit containing a newly released version", title: "Publish Release", emoji: "\u{1F680} ", hidden: true, semverBump: "none", changelog: { title: "Publish Release", hidden: true } } }; var DEFAULT_COMMIT_QUESTIONS = { type: { type: "select", title: "Commit Type", description: "Select the commit type that best describes your changes", enum: Object.keys(DEFAULT_COMMIT_TYPES).filter((type) => DEFAULT_COMMIT_TYPES[type].hidden !== true).reduce((ret, type) => { ret[type] = DEFAULT_COMMIT_TYPES[type]; return ret; }, {}), defaultValue: "chore", maxLength: 20, minLength: 3 }, scope: { type: "select", title: "Commit Scope", description: "Select the monorepo project that is primarily impacted by this change", enum: {}, defaultValue: "monorepo", maxLength: 50, minLength: 1 }, subject: { type: "input", title: "Commit Subject", description: "Write a short, imperative tense description of the change", maxLength: 150, minLength: 3 }, body: { type: "input", title: "Commit Body", description: "Provide a longer description of the change", maxLength: 600 }, isBreaking: { type: "confirm", title: "Breaking Changes", description: "Are there any breaking changes as a result of this commit?", defaultValue: false }, breakingBody: { type: "input", title: "Breaking Changes (Details)", description: "A BREAKING CHANGE commit requires a body. Please enter a longer description of the commit itself", when: /* @__PURE__ */ __name((answers) => answers.isBreaking === true, "when"), maxLength: 600, minLength: 3 }, isIssueAffected: { type: "confirm", title: "Open Issue Affected", description: "Does this change impact any open issues?", defaultValue: false }, issuesBody: { type: "input", title: "Open Issue Affected (Details)", description: "If issues are closed, the commit requires a body. Please enter a longer description of the commit itself", when: /* @__PURE__ */ __name((answers) => answers.isIssueAffected === true, "when"), maxLength: 600, minLength: 3 } }; var RuleConfigSeverity; (function(RuleConfigSeverity2) { RuleConfigSeverity2[RuleConfigSeverity2["Disabled"] = 0] = "Disabled"; RuleConfigSeverity2[RuleConfigSeverity2["Warning"] = 1] = "Warning"; RuleConfigSeverity2[RuleConfigSeverity2["Error"] = 2] = "Error"; })(RuleConfigSeverity || (RuleConfigSeverity = {})); // ../git-tools/src/release/config.ts var DEFAULT_CONVENTIONAL_COMMITS_CONFIG = { questions: DEFAULT_COMMIT_QUESTIONS, types: DEFAULT_COMMIT_TYPES }; // src/generators/release-version/generator.ts import { exec, execSync } from "node:child_process"; import { relative } from "node:path"; import { IMPLICIT_DEFAULT_RELEASE_GROUP } from "nx/src/command-line/release/config/config"; import { getFirstGitCommit, getLatestGitTagForPattern } from "nx/src/command-line/release/utils/git"; import { resolveSemverSpecifierFromConventionalCommits, resolveSemverSpecifierFromPrompt } from "nx/src/command-line/release/utils/resolve-semver-specifier"; import { isValidSemverSpecifier } from "nx/src/command-line/release/utils/semver"; import { deriveNewSemverVersion, validReleaseVersionPrefixes } from "nx/src/command-line/release/version"; import { interpolate } from "nx/src/tasks-runner/utils"; import { prerelease } from "semver"; async function releaseVersionGeneratorFn(tree, options, config) { writeInfo(`\u26A1 Running the Storm Release Version generator... `, config); const stopwatch = getStopwatch("Storm Release Version generator"); try { const workspaceRoot = findWorkspaceRoot(); writeDebug(`Loading the Storm Config from environment variables and storm.config.js file... - workspaceRoot: ${workspaceRoot}`, config); config = await getConfig(workspaceRoot); writeTrace(`Generator schema options \u2699\uFE0F ${Object.keys(options ?? {}).map((key) => ` - ${key}=${JSON.stringify(options[key])}`).join("\n")}`, config); const versionData = {}; if (options.specifier) { if (!isValidSemverSpecifier(options.specifier)) { throw new Error(`The given version specifier "${options.specifier}" is not valid. You provide an exact version or a valid semver keyword such as "major", "minor", "patch", etc.`); } options.specifier = options.specifier.replace(/^v/, ""); } if (options.versionPrefix && validReleaseVersionPrefixes.indexOf(options.versionPrefix) === -1) { throw new Error(`Invalid value for version.generatorOptions.versionPrefix: "${options.versionPrefix}" Valid values are: ${validReleaseVersionPrefixes.map((s) => `"${s}"`).join(", ")}`); } options.fallbackCurrentVersionResolver ??= "disk"; options.currentVersionResolver ??= "git-tag"; const projects = options.projects; const createResolvePackageRoot = /* @__PURE__ */ __name((customPackageRoot) => (projectNode) => { if (projectNode?.data?.root === config?.workspaceRoot || projectNode?.data?.root === ".") { return config?.workspaceRoot ?? findWorkspaceRoot(); } if (!customPackageRoot) { return projectNode.data.root; } return interpolate(customPackageRoot, { workspaceRoot: "", projectRoot: projectNode.data.root, projectName: projectNode.name }); }, "createResolvePackageRoot"); const resolvePackageRoot = createResolvePackageRoot(options.packageRoot); const projectNameToPackageRootMap = /* @__PURE__ */ new Map(); for (const project of projects) { projectNameToPackageRootMap.set(project.name, resolvePackageRoot(project)); } let currentVersion = null; let currentVersionResolvedFromFallback = false; let latestMatchingGitTag = null; let specifier = options.specifier ? options.specifier : void 0; for (const project of projects) { const projectName = project.name; const packageRoot = projectNameToPackageRootMap.get(projectName); const packageJsonPath = joinPathFragments(packageRoot ?? "./", "package.json"); const cargoTomlPath = joinPathFragments(packageRoot ?? "./", "Cargo.toml"); if (!tree.exists(packageJsonPath) && !tree.exists(cargoTomlPath)) { throw new Error(`The project "${projectName}" does not have a package.json available at ${packageJsonPath} or a Cargo.toml file available at ${cargoTomlPath}. To fix this you will either need to add a package.json or Cargo.toml file at that location, or configure "release" within your nx.json to exclude "${projectName}" from the current release group, or amend the packageRoot configuration to point to where the package.json should be.`); } const workspaceRelativePackagePath = relative(config?.workspaceRoot ?? findWorkspaceRoot(), tree.exists(packageJsonPath) ? packageJsonPath : cargoTomlPath); const log = /* @__PURE__ */ __name((msg) => { writeInfo(`${projectName}: ${msg}`, config); }, "log"); writeInfo(`Running release version for project: ${project.name}`, config); let packageName; let currentVersionFromDisk; if (tree.exists(packageJsonPath)) { const projectPackageJson = readJson(tree, packageJsonPath); log(`\u{1F50D} Reading data for package "${projectPackageJson.name}" from ${workspaceRelativePackagePath}`); packageName = projectPackageJson.name; currentVersionFromDisk = projectPackageJson.version; } else if (tree.exists(cargoTomlPath)) { const cargoToml = parseCargoToml(tree.read(cargoTomlPath)?.toString("utf-8")); log(`\u{1F50D} Reading data for package "${cargoToml.package.name}" from ${workspaceRelativePackagePath}`); packageName = cargoToml.package.name; currentVersionFromDisk = cargoToml.package.version; if (options.currentVersionResolver === "registry") { options.currentVersionResolver = "disk"; } } else { throw new Error(`The project "${projectName}" does not have a package.json available at ${workspaceRelativePackagePath} or a Cargo.toml file available at ${cargoTomlPath}. To fix this you will either need to add a package.json or Cargo.toml file at that location, or configure "release" within your nx.json to exclude "${projectName}" from the current release group, or amend the packageRoot configuration to point to where the package.json should be.`); } switch (options.currentVersionResolver) { case "registry": { const metadata = options.currentVersionResolverMetadata; const npmRegistry = metadata?.registry ?? await getNpmRegistry(); const githubRegistry = metadata?.registry ?? await getGitHubRegistry(); const tag = metadata?.tag ?? "latest"; if (options.releaseGroup.projectsRelationship === "independent") { try { currentVersion = await new Promise((resolve, reject) => { exec(`npm view ${packageName} version --registry=${npmRegistry} --tag=${tag}`, (error, stdout, stderr) => { if (error) { return reject(error); } if (stderr) { return reject(stderr); } return resolve(stdout.trim()); }); }); log(`\u{1F4C4} Resolved the current version as ${currentVersion} for tag "${tag}" from registry ${npmRegistry}`); } catch (_) { try { currentVersion = await new Promise((resolve, reject) => { exec(`npm view ${packageName} version --registry=${githubRegistry} --tag=${tag}`, (error, stdout, stderr) => { if (error) { return reject(error); } if (stderr) { return reject(stderr); } return resolve(stdout.trim()); }); }); log(`\u{1F4C4} Resolved the current version as ${currentVersion} for tag "${tag}" from registry ${githubRegistry}`); } catch (_2) { if (options.fallbackCurrentVersionResolver === "disk") { log(`\u{1F4C4} Unable to resolve the current version from the registry ${npmRegistry}${githubRegistry ? ` or ${githubRegistry}` : ""}. Falling back to the version on disk of ${currentVersionFromDisk}`); currentVersion = currentVersionFromDisk; currentVersionResolvedFromFallback = true; } else { throw new Error(`Unable to resolve the current version from the registry ${npmRegistry}${githubRegistry ? ` or ${githubRegistry}` : ""}. Please ensure that the package exists in the registry in order to use the "registry" currentVersionResolver. Alternatively, you can use the --first-release option or set "release.version.generatorOptions.fallbackCurrentVersionResolver" to "disk" in order to fallback to the version on disk when the registry lookup fails.`); } } } } else { if (currentVersionResolvedFromFallback) { log(`\u{1F4C4} Using the current version ${currentVersion} already resolved from disk fallback.`); } else { log(`\u{1F4C4} Using the current version ${currentVersion} already resolved from the registry ${npmRegistry ?? githubRegistry}`); } } break; } case "disk": currentVersion = currentVersionFromDisk; log(`\u{1F4C4} Resolved the current version as ${currentVersion} from ${packageJsonPath}`); break; case "git-tag": { if ( // We always need to independently resolve the current version from git tag per project if the projects are independent options.releaseGroup.projectsRelationship === "independent" ) { const releaseTagPattern = options.releaseGroup.releaseTagPattern; latestMatchingGitTag = await getLatestGitTagForPattern(releaseTagPattern, { projectName: project.name }); if (!latestMatchingGitTag) { if (currentVersionFromDisk) { log(`\u{1F4C4} Unable to resolve the current version from git tag using pattern "${releaseTagPattern}". Falling back to the version on disk of ${currentVersionFromDisk}`); currentVersion = currentVersionFromDisk; } else { log(`No git tags matching pattern "${releaseTagPattern}" for project "${project.name}" were found. This process also could not determine the version by checking the package files on disk, so we will attempt to use the default version value: "0.0.1".`); currentVersion = "0.0.1"; } currentVersionResolvedFromFallback = true; } else { currentVersion = latestMatchingGitTag.extractedVersion; log(`\u{1F4C4} Resolved the current version as ${currentVersion} from git tag "${latestMatchingGitTag.tag}".`); } } else { if (currentVersionResolvedFromFallback) { log(`\u{1F4C4} Using the current version ${currentVersion} already resolved from disk fallback.`); } else { log(`\u{1F4C4} Using the current version ${currentVersion} already resolved from git tag "${latestMatchingGitTag.tag}".`); } } break; } default: throw new Error(`Invalid value for options.currentVersionResolver: ${options.currentVersionResolver}`); } if (options.specifier) { log(`\u{1F4C4} Using the provided version specifier "${options.specifier}".`); } if (specifier === void 0 || options.releaseGroup.projectsRelationship === "independent" && !options.specifier) { const specifierSource = options.specifierSource; switch (specifierSource) { case "conventional-commits": { if (options.currentVersionResolver !== "git-tag") { throw new Error(`Invalid currentVersionResolver "${options.currentVersionResolver}" provided for release group "${options.releaseGroup.name}". Must be "git-tag" when "specifierSource" is "conventional-commits"`); } const affectedProjects = options.releaseGroup.projectsRelationship === "independent" ? [ projectName ] : projects.map((p) => p.name); let previousVersionRef = latestMatchingGitTag?.tag ? latestMatchingGitTag.tag : await getFirstGitCommit(); if (!previousVersionRef) { log(`Unable to determine previous version ref for the projects ${affectedProjects.join(", ")}. This is likely a bug in Storm's Release Versioning. We will attempt to use the default version value "0.0.1" and continue with the process.`); previousVersionRef = "0.0.1"; } specifier = await resolveSemverSpecifierFromConventionalCommits(previousVersionRef, options.projectGraph, affectedProjects, DEFAULT_CONVENTIONAL_COMMITS_CONFIG) ?? void 0; if (!specifier) { log("\u{1F6AB} No changes were detected using git history and the conventional commits standard."); break; } if (currentVersion && prerelease(currentVersion)) { specifier = "prerelease"; log(`\u{1F4C4} Resolved the specifier as "${specifier}" since the current version is a prerelease.`); } else { log(`\u{1F4C4} Resolved the specifier as "${specifier}" using git history and the conventional commits standard.`); } break; } case "prompt": { const maybeLogReleaseGroup = /* @__PURE__ */ __name((log2) => { if (options.releaseGroup.name === IMPLICIT_DEFAULT_RELEASE_GROUP) { return log2; } return `${log2} within release group "${options.releaseGroup.name}"`; }, "maybeLogReleaseGroup"); if (options.releaseGroup.projectsRelationship === "independent") { specifier = await resolveSemverSpecifierFromPrompt(`${maybeLogReleaseGroup(`What kind of change is this for project "${projectName}"`)}?`, `${maybeLogReleaseGroup(`What is the exact version for project "${projectName}"`)}?`); } else { specifier = await resolveSemverSpecifierFromPrompt(`${maybeLogReleaseGroup(`What kind of change is this for the ${projects.length} matched projects(s)`)}?`, `${maybeLogReleaseGroup(`What is the exact version for the ${projects.length} matched project(s)`)}?`); } break; } default: throw new Error(`Invalid specifierSource "${specifierSource}" provided. Must be one of "prompt" or "conventional-commits"`); } } const localPackageDependencies = resolveLocalPackageDependencies( tree, options.projectGraph, projects.filter((project2) => project2?.data?.root && project2?.data?.root !== config?.workspaceRoot), projectNameToPackageRootMap, resolvePackageRoot, // includeAll when the release group is independent, as we may be filtering to a specific subset of projects, but we still want to update their dependents options.releaseGroup.projectsRelationship === "independent", tree.exists(packageJsonPath) ); const dependentProjects = Object.values(localPackageDependencies).flat().filter((localPackageDependency) => { return localPackageDependency.target === project.name; }); if (!currentVersion) { throw new Error(`Unable to determine the current version for project "${projectName}"`); } versionData[projectName] = { currentVersion: currentVersion ? currentVersion : "0.0.1", dependentProjects, newVersion: null // will stay as null in the final result in the case that no changes are detected }; if (!specifier) { log(`\u{1F6AB} Skipping versioning "${packageName}" as no changes were detected.`); continue; } const newVersion = deriveNewSemverVersion(currentVersion, specifier, options.preid); if (versionData[projectName]) { versionData[projectName].newVersion = newVersion; } if (tree.exists(packageJsonPath)) { const projectPackageJson = readJson(tree, packageJsonPath); writeJson(tree, packageJsonPath, { ...projectPackageJson, version: newVersion }); } else if (tree.exists(cargoTomlPath)) { const cargoToml = parseCargoToml(tree.read(cargoTomlPath)?.toString("utf-8")); cargoToml.package ??= {}; cargoToml.package.version = newVersion; tree.write(cargoTomlPath, stringifyCargoToml(cargoToml)); } log(`\u270D\uFE0F New version ${newVersion} written to ${workspaceRelativePackagePath}`); if (dependentProjects.length > 0) { log(`\u270D\uFE0F Applying new version ${newVersion} to ${dependentProjects.length} ${dependentProjects.length > 1 ? "packages which depend" : "package which depends"} on ${project.name}`); } for (const dependentProject of dependentProjects) { const dependentPackageRoot = projectNameToPackageRootMap.get(dependentProject.source); if (!dependentPackageRoot) { throw new Error(`The dependent project "${dependentProject.source}" does not have a packageRoot available. Projects with packageRoot configured: ${Array.from(projectNameToPackageRootMap.keys()).join(", ")}`); } const dependentPackageJsonPath = joinPathFragments(dependentPackageRoot, "package.json"); const dependentCargoTomlPath = joinPathFragments(dependentPackageRoot, "Cargo.toml"); if (tree.exists(dependentPackageJsonPath)) { updateJson(tree, dependentPackageJsonPath, (json) => { let versionPrefix = options.versionPrefix ?? "auto"; if (versionPrefix === "auto") { versionPrefix = ""; const current = json[dependentProject.dependencyCollection][packageName]; if (current) { const prefixMatch = current.match(/^[~^]/); if (prefixMatch) { versionPrefix = prefixMatch[0]; } else { versionPrefix = ""; } } } json[dependentProject.dependencyCollection][packageName] = `${versionPrefix}${newVersion}`; return json; }); } else if (tree.exists(dependentCargoTomlPath)) { const dependentPkg = parseCargoTomlWithTree(tree, dependentPackageRoot, dependentProject.source); let versionPrefix = options.versionPrefix ?? "auto"; let updatedDependencyData = ""; for (const dependency of Object.entries(dependentPkg[dependentProject.dependencyCollection] ?? {})) { const [dependencyName, dependencyData] = dependency; if (dependencyName !== dependentProject.target) { continue; } if (versionPrefix === "auto") { versionPrefix = ""; if (currentVersion) { const dependencyVersion = typeof dependencyData === "string" ? dependencyData : dependencyData.version; const prefixMatch = dependencyVersion?.match(/^[~^=]/); if (prefixMatch) { versionPrefix = prefixMatch[0]; } else { versionPrefix = ""; } if (versionPrefix === "^") { if (typeof dependencyData !== "string" && !dependencyData.version?.startsWith("^")) { versionPrefix = ""; } } } } const newVersionWithPrefix = `${versionPrefix}${newVersion}`; updatedDependencyData = typeof dependencyData === "string" ? newVersionWithPrefix : { ...dependencyData, version: newVersionWithPrefix }; break; } const cargoTomlToUpdate = joinPathFragments(dependentPackageRoot, "Cargo.toml"); modifyCargoTable(dependentPkg, dependentProject.dependencyCollection, dependentProject.target, updatedDependencyData); tree.write(cargoTomlToUpdate, stringifyCargoToml(dependentPkg)); } } } await formatFiles(tree); writeSuccess(`Completed running the Storm Release Version generator! `, config); return { data: versionData, callback: /* @__PURE__ */ __name(async (tree2, opts) => { output.logSingleLine("Updating Cargo.lock file"); const cwd = tree2.root; const updatedFiles = await updateLockFile(cwd, opts) ?? []; const updatedCargoPackages = []; for (const [projectName, projectVersionData] of Object.entries(versionData)) { const project = projects.find((proj) => proj.name === projectName); if (projectVersionData.newVersion && project?.name && projectNameToPackageRootMap.get(project.name)) { const projectRoot = projectNameToPackageRootMap.get(project.name); if (projectRoot && tree2.exists(joinPathFragments(projectRoot, "Cargo.toml"))) { updatedCargoPackages.push(projectName); } } } if (updatedCargoPackages.length > 0) { execSync(`cargo update ${updatedCargoPackages.join(" ")}`, { maxBuffer: 1024 * 1024 * 1024, env: { ...process.env }, cwd: tree2.root }); if (hasGitDiff("Cargo.lock")) { updatedFiles.push("Cargo.lock"); } } return updatedFiles; }, "callback") }; } catch (error) { writeFatal("A fatal error occurred while running the Storm Release Version generator - the process was forced to terminate", config); writeError(`An exception was thrown in the Storm Release Version generator's process - Details: ${error.message} - Stacktrace: ${error.stack}`, config); throw new Error(`An exception was thrown in the Storm Release Version generator's process - Details: ${error.message}`, { cause: error }); } finally { stopwatch(); } } __name(releaseVersionGeneratorFn, "releaseVersionGeneratorFn"); var generator_default = releaseVersionGeneratorFn; async function getNpmRegistry() { if (process.env.STORM_REGISTRY_NPM) { return process.env.STORM_REGISTRY_NPM; } const registry = await new Promise((resolve, reject) => { exec("npm config get registry", (error, stdout, stderr) => { if (error) { return reject(error); } if (stderr) { return reject(stderr); } return resolve(stdout.trim()); }); }); return registry ? registry : "https://registry.npmjs.org"; } __name(getNpmRegistry, "getNpmRegistry"); function getGitHubRegistry() { if (process.env.STORM_REGISTRY_GITHUB) { return process.env.STORM_REGISTRY_GITHUB; } return "https://npm.pkg.github.com"; } __name(getGitHubRegistry, "getGitHubRegistry"); function hasGitDiff(filePath) { try { const result = execSync(`git diff --name-only "${filePath}"`).toString(); return result.trim() === filePath; } catch (_) { return false; } } __name(hasGitDiff, "hasGitDiff"); function resolveLocalPackageDependencies(tree, projectGraph, filteredProjects, projectNameToPackageRootMap, resolvePackageRoot, includeAll = false, isNodeProject = true) { if (isNodeProject) { return resolveLocalPackageJsonDependencies(tree, projectGraph, filteredProjects, projectNameToPackageRootMap, resolvePackageRoot, includeAll); } return resolveLocalPackageCargoDependencies(tree, projectGraph, filteredProjects, projectNameToPackageRootMap, resolvePackageRoot, includeAll); } __name(resolveLocalPackageDependencies, "resolveLocalPackageDependencies"); function resolveLocalPackageCargoDependencies(tree, projectGraph, filteredProjects, projectNameToPackageRootMap, resolvePackageRoot, includeAll = false) { const localPackageDependencies = {}; const projects = includeAll ? Object.values(projectGraph.nodes) : filteredProjects; for (const projectNode of projects) { let packageRoot = projectNameToPackageRootMap.get(projectNode.name); if (!packageRoot && includeAll) { packageRoot = resolvePackageRoot(projectNode); if (!packageRoot) { continue; } projectNameToPackageRootMap.set(projectNode.name, packageRoot); } const cargoTomlPath = joinPathFragments(packageRoot ?? "./", "Cargo.toml"); if (!tree.exists(cargoTomlPath)) { continue; } const projectDeps = projectGraph.dependencies[projectNode.name]; if (!projectDeps) { continue; } const localPackageDepsForProject = []; for (const dep of projectDeps) { const depProject = projectGraph.nodes[dep.target]; if (!depProject) { continue; } const depProjectRoot = projectNameToPackageRootMap.get(dep.target); if (!depProjectRoot) { throw new Error(`The project "${dep.target}" does not have a packageRoot available.`); } const cargoToml = parseCargoTomlWithTree(tree, resolvePackageRoot(projectNode), projectNode.name); const dependencies = cargoToml.dependencies ?? {}; const devDependencies = cargoToml["dev-dependencies"] ?? {}; const dependencyCollection = dependencies[depProject.name] ? "dependencies" : devDependencies[depProject.name] ? "dev-dependencies" : null; if (!dependencyCollection) { throw new Error(`The project "${projectNode.name}" does not have a local dependency on "${depProject.name}" in its Cargo.toml`); } localPackageDepsForProject.push({ ...dep, dependencyCollection }); } localPackageDependencies[projectNode.name] = localPackageDepsForProject; } return localPackageDependencies; } __name(resolveLocalPackageCargoDependencies, "resolveLocalPackageCargoDependencies"); export { releaseVersionGeneratorFn, generator_default };