Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7bb43ad478 | |||
| 8dcaf1c631 | |||
| 422761806d | |||
| 31360240a9 |
15
changelog.md
15
changelog.md
@@ -1,5 +1,20 @@
|
||||
# Changelog
|
||||
|
||||
## 2025-10-23 - 1.18.8 - fix(mod_commit)
|
||||
Improve commit workflow: detect project type and current branch; add robust version bump helpers for npm/deno
|
||||
|
||||
- Add mod_commit/mod.helpers.ts with utilities: detectCurrentBranch(), detectProjectType(), bumpProjectVersion(), bumpDenoVersion(), bumpNpmVersion(), syncVersionToDenoJson(), and calculateNewVersion()
|
||||
- Refactor ts/mod_commit/index.ts to use the new helpers: bumpProjectVersion(projectType, ... ) instead of a hard npm version call and push the actual current branch instead of hardcoding 'master'
|
||||
- Support bumping versions for npm-only, deno-only, and hybrid (both) projects and synchronize versions from package.json to deno.json when applicable
|
||||
- Improve branch detection with a fallback to 'master' and informative logging on detection failures
|
||||
- Add local Claude settings file (.claude/settings.local.json) (editor/CI config) — no code behavior change but included in diff
|
||||
|
||||
## 2025-09-07 - 1.18.7 - fix(claude)
|
||||
Add .claude local settings to whitelist dev tool permissions
|
||||
|
||||
- Add .claude/settings.local.json to configure allowed permissions for local AI/tooling helpers (Bash commands, WebFetch, and mcp_serena actions).
|
||||
- Disable enableAllProjectMcpServers (set to false) to limit automatic project MCP server usage.
|
||||
|
||||
## 2025-09-07 - 1.18.6 - fix(deps)
|
||||
Bump dependency versions and add local Claude settings
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@git.zone/cli",
|
||||
"private": false,
|
||||
"version": "1.18.6",
|
||||
"version": "1.18.8",
|
||||
"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.",
|
||||
"main": "dist_ts/index.ts",
|
||||
"typings": "dist_ts/index.d.ts",
|
||||
|
||||
1718
pnpm-lock.yaml
generated
1718
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@git.zone/cli',
|
||||
version: '1.18.6',
|
||||
version: '1.18.8',
|
||||
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.'
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import * as plugins from './mod.plugins.js';
|
||||
import * as paths from '../paths.js';
|
||||
import { logger } from '../gitzone.logging.js';
|
||||
import * as helpers from './mod.helpers.js';
|
||||
|
||||
export const run = async (argvArg: any) => {
|
||||
if (argvArg.format) {
|
||||
@@ -113,12 +114,18 @@ export const run = async (argvArg: any) => {
|
||||
logger.log('info', `Staging files for commit:`);
|
||||
await smartshellInstance.exec(`git add -A`);
|
||||
await smartshellInstance.exec(`git commit -m "${commitString}"`);
|
||||
await smartshellInstance.exec(`npm version ${commitVersionType}`);
|
||||
|
||||
// Detect project type and bump version accordingly
|
||||
const projectType = await helpers.detectProjectType();
|
||||
await helpers.bumpProjectVersion(projectType, commitVersionType);
|
||||
|
||||
if (
|
||||
answerBucket.getAnswerFor('pushToOrigin') &&
|
||||
!(process.env.CI === 'true')
|
||||
) {
|
||||
await smartshellInstance.exec(`git push origin master --follow-tags`);
|
||||
// Detect current branch instead of hardcoding "master"
|
||||
const currentBranch = await helpers.detectCurrentBranch();
|
||||
await smartshellInstance.exec(`git push origin ${currentBranch} --follow-tags`);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
204
ts/mod_commit/mod.helpers.ts
Normal file
204
ts/mod_commit/mod.helpers.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
import * as plugins from './mod.plugins.js';
|
||||
import * as paths from '../paths.js';
|
||||
import { logger } from '../gitzone.logging.js';
|
||||
|
||||
export type ProjectType = 'npm' | 'deno' | 'both' | 'none';
|
||||
export type VersionType = 'patch' | 'minor' | 'major';
|
||||
|
||||
/**
|
||||
* Detects the current git branch
|
||||
* @returns The current branch name, defaults to 'master' if detection fails
|
||||
*/
|
||||
export async function detectCurrentBranch(): Promise<string> {
|
||||
try {
|
||||
const smartshellInstance = new plugins.smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
sourceFilePaths: [],
|
||||
});
|
||||
const result = await smartshellInstance.exec('git branch --show-current');
|
||||
const branchName = result.stdout.trim();
|
||||
|
||||
if (!branchName) {
|
||||
logger.log('warn', 'Could not detect current branch, falling back to "master"');
|
||||
return 'master';
|
||||
}
|
||||
|
||||
logger.log('info', `Detected current branch: ${branchName}`);
|
||||
return branchName;
|
||||
} catch (error) {
|
||||
logger.log('warn', `Failed to detect branch: ${error.message}, falling back to "master"`);
|
||||
return 'master';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Detects the project type based on presence of package.json and/or deno.json
|
||||
* @returns The project type
|
||||
*/
|
||||
export async function detectProjectType(): Promise<ProjectType> {
|
||||
const packageJsonPath = plugins.path.join(paths.cwd, 'package.json');
|
||||
const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json');
|
||||
|
||||
const hasPackageJson = await plugins.smartfile.fs.fileExists(packageJsonPath);
|
||||
const hasDenoJson = await plugins.smartfile.fs.fileExists(denoJsonPath);
|
||||
|
||||
if (hasPackageJson && hasDenoJson) {
|
||||
logger.log('info', 'Detected dual project (npm + deno)');
|
||||
return 'both';
|
||||
} else if (hasPackageJson) {
|
||||
logger.log('info', 'Detected npm project');
|
||||
return 'npm';
|
||||
} else if (hasDenoJson) {
|
||||
logger.log('info', 'Detected deno project');
|
||||
return 'deno';
|
||||
} else {
|
||||
throw new Error('No package.json or deno.json found in current directory');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a semantic version string and bumps it according to the version type
|
||||
* @param currentVersion Current version string (e.g., "1.2.3")
|
||||
* @param versionType Type of version bump
|
||||
* @returns New version string
|
||||
*/
|
||||
function calculateNewVersion(currentVersion: string, versionType: VersionType): string {
|
||||
const versionMatch = currentVersion.match(/^(\d+)\.(\d+)\.(\d+)/);
|
||||
|
||||
if (!versionMatch) {
|
||||
throw new Error(`Invalid version format: ${currentVersion}`);
|
||||
}
|
||||
|
||||
let [, major, minor, patch] = versionMatch.map(Number);
|
||||
|
||||
switch (versionType) {
|
||||
case 'major':
|
||||
major += 1;
|
||||
minor = 0;
|
||||
patch = 0;
|
||||
break;
|
||||
case 'minor':
|
||||
minor += 1;
|
||||
patch = 0;
|
||||
break;
|
||||
case 'patch':
|
||||
patch += 1;
|
||||
break;
|
||||
}
|
||||
|
||||
return `${major}.${minor}.${patch}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Bumps the version in deno.json
|
||||
* @param versionType Type of version bump
|
||||
* @returns The new version string
|
||||
*/
|
||||
export async function bumpDenoVersion(versionType: VersionType): Promise<string> {
|
||||
const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json');
|
||||
|
||||
try {
|
||||
// Read 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
|
||||
);
|
||||
|
||||
return newVersion;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to bump deno.json version: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bumps the version in package.json using npm version command
|
||||
* @param versionType Type of version bump
|
||||
* @returns The new version string
|
||||
*/
|
||||
async function bumpNpmVersion(versionType: VersionType): Promise<string> {
|
||||
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
|
||||
* @param version The version to sync
|
||||
*/
|
||||
async function syncVersionToDenoJson(version: string): Promise<void> {
|
||||
const denoJsonPath = plugins.path.join(paths.cwd, 'deno.json');
|
||||
|
||||
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
|
||||
);
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to sync version to deno.json: ${error.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bumps the project version based on project type
|
||||
* @param projectType The detected project type
|
||||
* @param versionType The type of version bump
|
||||
* @returns The new version string
|
||||
*/
|
||||
export async function bumpProjectVersion(
|
||||
projectType: ProjectType,
|
||||
versionType: VersionType
|
||||
): Promise<string> {
|
||||
switch (projectType) {
|
||||
case 'npm':
|
||||
return await bumpNpmVersion(versionType);
|
||||
|
||||
case 'deno':
|
||||
return await bumpDenoVersion(versionType);
|
||||
|
||||
case 'both': {
|
||||
// Bump npm version first (it handles git tags)
|
||||
const newVersion = await bumpNpmVersion(versionType);
|
||||
// Then sync to deno.json
|
||||
await syncVersionToDenoJson(newVersion);
|
||||
return newVersion;
|
||||
}
|
||||
|
||||
case 'none':
|
||||
throw new Error('Cannot bump version: no package.json or deno.json found');
|
||||
|
||||
default:
|
||||
throw new Error(`Unknown project type: ${projectType}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user