From fff1d393382e0b79ff4d1a28e2d21235cf793a4c Mon Sep 17 00:00:00 2001 From: Juergen Kunz Date: Wed, 5 Nov 2025 22:55:29 +0000 Subject: [PATCH] fix(mod_commit): Refactor version bumping to a unified implementation for npm and Deno; remove npm-exec based helpers and add file-based version readers/updaters to avoid npm warning pollution --- changelog.md | 10 ++ readme.hints.md | 20 ++++ ts/00_commitinfo_data.ts | 2 +- ts/mod_commit/mod.helpers.ts | 192 +++++++++++++---------------------- 4 files changed, 102 insertions(+), 122 deletions(-) diff --git a/changelog.md b/changelog.md index a2f0e1c..123e4d8 100644 --- a/changelog.md +++ b/changelog.md @@ -1,5 +1,15 @@ # Changelog +## 2025-11-05 - 1.19.9 - fix(mod_commit) +Refactor version bumping to a unified implementation for npm and Deno; remove npm-exec based helpers and add file-based version readers/updaters to avoid npm warning pollution + +- Removed legacy npm/deno-specific helpers (bumpNpmVersion, syncVersionToDenoJson, bumpDenoVersion) that relied on executing npm and caused warning pollution +- Added readCurrentVersion() to read version from package.json or deno.json +- Added updateVersionFile() helper to write version directly into JSON files +- Added unified bumpProjectVersion() that handles npm, deno and both with a single code path; reuses calculateNewVersion() +- Stages updated files, commits v and creates a tag v +- Benefits: no npm warning pollution in deno.json, simpler git history, consistent behavior across project types + ## 2025-11-04 - 1.19.8 - fix(package.json) Bump @git.zone/tsdoc dependency to ^1.9.2 diff --git a/readme.hints.md b/readme.hints.md index d6b358f..6db1c3a 100644 --- a/readme.hints.md +++ b/readme.hints.md @@ -89,6 +89,26 @@ The format module is responsible for project standardization: 5. **Performance Optimizations**: Parallel execution and caching 6. **Reporting**: Diff views, statistics, verbose logging 7. **Architecture**: Clean separation of concerns with new classes +8. **Unified Version Bumping**: Self-managed version updates eliminating npm warning pollution in deno.json + +### Version Bumping Refactor (Latest) + +The commit module's version bumping has been refactored to eliminate npm command dependencies: + +**Changes:** +- Removed `bumpNpmVersion()` - was causing npm warnings to pollute deno.json +- Removed `syncVersionToDenoJson()` - no longer needed with unified approach +- Removed separate `bumpDenoVersion()` - replaced by unified implementation +- Added `readCurrentVersion()` helper - reads from either package.json or deno.json +- Added `updateVersionFile()` helper - updates JSON files directly +- Unified `bumpProjectVersion()` - handles npm/deno/both with single clean code path + +**Benefits:** +- No npm warning pollution in version fields +- Full control over version bumping process +- Simpler git history (no amending, no force-tagging) +- Same code path for all project types +- Reuses existing `calculateNewVersion()` function ## Development Tips diff --git a/ts/00_commitinfo_data.ts b/ts/00_commitinfo_data.ts index b39a1fb..31c4585 100644 --- a/ts/00_commitinfo_data.ts +++ b/ts/00_commitinfo_data.ts @@ -3,6 +3,6 @@ */ export const commitinfo = { name: '@git.zone/cli', - version: '1.19.8', + version: '1.19.9', description: 'A comprehensive CLI tool for enhancing and managing local development workflows with gitzone utilities, focusing on project setup, version control, code formatting, and template management.' } diff --git a/ts/mod_commit/mod.helpers.ts b/ts/mod_commit/mod.helpers.ts index 0fc8f93..fb40f4a 100644 --- a/ts/mod_commit/mod.helpers.ts +++ b/ts/mod_commit/mod.helpers.ts @@ -91,118 +91,47 @@ function calculateNewVersion(currentVersion: string, versionType: VersionType): } /** - * Bumps the version in deno.json, commits the change, and creates a tag - * @param versionType Type of version bump - * @returns The new version string + * Reads the current version from package.json or deno.json + * @param projectType The project type to determine which file to read + * @returns The current version string */ -export async function bumpDenoVersion(versionType: VersionType): Promise { - const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json'); - const smartshellInstance = new plugins.smartshell.Smartshell({ - executor: 'bash', - sourceFilePaths: [], - }); +function readCurrentVersion(projectType: ProjectType): string { + if (projectType === 'npm' || projectType === 'both') { + const packageJsonPath = plugins.path.join(paths.cwd, 'package.json'); + const packageJson = plugins.smartfile.fs.toObjectSync(packageJsonPath) as { version?: string }; - try { - // Read deno.json - const denoConfig = plugins.smartfile.fs.toObjectSync( - denoJsonPath - ) as { version?: string }; + if (!packageJson.version) { + throw new Error('package.json does not contain a version field'); + } + return packageJson.version; + } else { + const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json'); + const denoConfig = plugins.smartfile.fs.toObjectSync(denoJsonPath) as { version?: string }; if (!denoConfig.version) { throw new Error('deno.json does not contain a version field'); } - - const currentVersion = denoConfig.version; - const newVersion = calculateNewVersion(currentVersion, versionType); - - logger.log('info', `Bumping deno.json version: ${currentVersion} → ${newVersion}`); - - // Update version - denoConfig.version = newVersion; - - // Write back to disk - await plugins.smartfile.memory.toFs( - JSON.stringify(denoConfig, null, 2) + '\n', - denoJsonPath - ); - - // Stage the deno.json file - await smartshellInstance.exec('git add deno.json'); - - // Commit the version bump - await smartshellInstance.exec(`git commit -m "v${newVersion}"`); - - // Create the version tag - await smartshellInstance.exec(`git tag v${newVersion} -m "v${newVersion}"`); - - logger.log('info', `Created commit and tag v${newVersion}`); - - return newVersion; - } catch (error) { - throw new Error(`Failed to bump deno.json version: ${error.message}`); + return denoConfig.version; } } /** - * Bumps the version in package.json using npm version command - * @param versionType Type of version bump - * @returns The new version string + * Updates the version field in a JSON file (package.json or deno.json) + * @param filePath Path to the JSON file + * @param newVersion The new version to write */ -async function bumpNpmVersion(versionType: VersionType): Promise { - const smartshellInstance = new plugins.smartshell.Smartshell({ - executor: 'bash', - sourceFilePaths: [], - }); - - logger.log('info', `Bumping package.json version using npm version ${versionType}`); - const result = await smartshellInstance.exec(`npm version ${versionType}`); - - // npm version returns the new version with a 'v' prefix, e.g., "v1.2.3" - const newVersion = result.stdout.trim().replace(/^v/, ''); - return newVersion; -} - -/** - * Syncs the version from package.json to deno.json and amends the npm commit - * @param version The version to sync - */ -async function syncVersionToDenoJson(version: string): Promise { - const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json'); - const smartshellInstance = new plugins.smartshell.Smartshell({ - executor: 'bash', - sourceFilePaths: [], - }); - - try { - const denoConfig = plugins.smartfile.fs.toObjectSync( - denoJsonPath - ) as { version?: string }; - - logger.log('info', `Syncing version to deno.json: ${version}`); - denoConfig.version = version; - - await plugins.smartfile.memory.toFs( - JSON.stringify(denoConfig, null, 2) + '\n', - denoJsonPath - ); - - // Stage the deno.json file - await smartshellInstance.exec('git add deno.json'); - - // Amend the npm version commit to include deno.json - await smartshellInstance.exec('git commit --amend --no-edit'); - - // Re-create the tag with force to update it - await smartshellInstance.exec(`git tag -fa v${version} -m "v${version}"`); - - logger.log('info', `Amended commit to include deno.json and updated tag v${version}`); - } catch (error) { - throw new Error(`Failed to sync version to deno.json: ${error.message}`); - } +async function updateVersionFile(filePath: string, newVersion: string): Promise { + const config = plugins.smartfile.fs.toObjectSync(filePath) as { version?: string }; + config.version = newVersion; + await plugins.smartfile.memory.toFs( + JSON.stringify(config, null, 2) + '\n', + filePath + ); } /** * Bumps the project version based on project type + * Handles npm-only, deno-only, and dual projects with unified logic * @param projectType The detected project type * @param versionType The type of version bump * @param currentStep The current step number for progress display @@ -215,6 +144,10 @@ export async function bumpProjectVersion( currentStep?: number, totalSteps?: number ): Promise { + if (projectType === 'none') { + throw new Error('Cannot bump version: no package.json or deno.json found'); + } + const projectEmoji = projectType === 'npm' ? '📦' : projectType === 'deno' ? '🦕' : '🔀'; const description = `🏷️ Bumping version (${projectEmoji} ${projectType})`; @@ -222,35 +155,52 @@ export async function bumpProjectVersion( ui.printStep(currentStep, totalSteps, description, 'in-progress'); } - let newVersion: string; + const smartshellInstance = new plugins.smartshell.Smartshell({ + executor: 'bash', + sourceFilePaths: [], + }); - switch (projectType) { - case 'npm': - newVersion = await bumpNpmVersion(versionType); - break; + try { + // 1. Read current version + const currentVersion = readCurrentVersion(projectType); - case 'deno': - newVersion = await bumpDenoVersion(versionType); - break; + // 2. Calculate new version (reuse existing function!) + const newVersion = calculateNewVersion(currentVersion, versionType); - case 'both': { - // Bump npm version first (it handles git tags) - newVersion = await bumpNpmVersion(versionType); - // Then sync to deno.json - await syncVersionToDenoJson(newVersion); - break; + logger.log('info', `Bumping version: ${currentVersion} → ${newVersion}`); + + // 3. Determine which files to update + const filesToUpdate: string[] = []; + const packageJsonPath = plugins.path.join(paths.cwd, 'package.json'); + const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json'); + + if (projectType === 'npm' || projectType === 'both') { + await updateVersionFile(packageJsonPath, newVersion); + filesToUpdate.push('package.json'); } - case 'none': - throw new Error('Cannot bump version: no package.json or deno.json found'); + if (projectType === 'deno' || projectType === 'both') { + await updateVersionFile(denoJsonPath, newVersion); + filesToUpdate.push('deno.json'); + } - default: - throw new Error(`Unknown project type: ${projectType}`); + // 4. Stage all updated files + await smartshellInstance.exec(`git add ${filesToUpdate.join(' ')}`); + + // 5. Create version commit + await smartshellInstance.exec(`git commit -m "v${newVersion}"`); + + // 6. Create version tag + await smartshellInstance.exec(`git tag v${newVersion} -m "v${newVersion}"`); + + logger.log('info', `Created commit and tag v${newVersion}`); + + if (currentStep && totalSteps) { + ui.printStep(currentStep, totalSteps, description, 'done'); + } + + return newVersion; + } catch (error) { + throw new Error(`Failed to bump project version: ${error.message}`); } - - if (currentStep && totalSteps) { - ui.printStep(currentStep, totalSteps, description, 'done'); - } - - return newVersion; }