fix(cli): improve changelog release handling and TypeScript compatibility
This commit is contained in:
@@ -35,7 +35,7 @@ export class GitzoneConfig {
|
||||
return gitzoneConfig;
|
||||
}
|
||||
|
||||
public data: IGitzoneConfigData;
|
||||
public data!: IGitzoneConfigData;
|
||||
|
||||
public async readConfigFromCwd() {
|
||||
const smartconfigInstance = new plugins.smartconfig.Smartconfig(paths.cwd);
|
||||
|
||||
+1
-1
@@ -105,7 +105,7 @@ export let run = async () => {
|
||||
const rawCliMode = await getRawCliMode();
|
||||
|
||||
// get packageInfo
|
||||
const projectInfo = new plugins.projectinfo.ProjectInfo(paths.packageDir);
|
||||
const projectInfo = await plugins.projectinfo.ProjectInfo.create(paths.packageDir);
|
||||
const projectInfoVersion = (projectInfo.npm as any)?.version;
|
||||
const packageVersion =
|
||||
typeof projectInfoVersion === "string" && projectInfoVersion.length > 0
|
||||
|
||||
+22
-8
@@ -19,6 +19,12 @@ export interface IPendingChangelog {
|
||||
isEmpty: boolean;
|
||||
}
|
||||
|
||||
interface IChangelogSection {
|
||||
start: number;
|
||||
bodyStart: number;
|
||||
end: number;
|
||||
}
|
||||
|
||||
const bucketForCommitType = (commitType: string): TChangelogBucket => {
|
||||
switch (commitType) {
|
||||
case "BREAKING CHANGE":
|
||||
@@ -48,7 +54,7 @@ const writeChangelog = async (filePath: string, content: string): Promise<void>
|
||||
const findPendingSection = (
|
||||
content: string,
|
||||
sectionName: string,
|
||||
): { start: number; bodyStart: number; end: number } | null => {
|
||||
): IChangelogSection | null => {
|
||||
const headingRegex = new RegExp(`^##\\s+${sectionName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")}\\s*$`, "m");
|
||||
const match = headingRegex.exec(content);
|
||||
if (!match || match.index === undefined) {
|
||||
@@ -123,9 +129,11 @@ export const readPendingChangelog = async (
|
||||
filePath: string,
|
||||
sectionName = "Pending",
|
||||
): Promise<IPendingChangelog> => {
|
||||
const content = await ensurePendingSection(filePath, sectionName);
|
||||
const pendingSection = findPendingSection(content, sectionName)!;
|
||||
const block = content.slice(pendingSection.bodyStart, pendingSection.end).trim();
|
||||
const content = await readChangelog(filePath);
|
||||
const pendingSection = findPendingSection(content, sectionName);
|
||||
const block = pendingSection
|
||||
? content.slice(pendingSection.bodyStart, pendingSection.end).trim()
|
||||
: "";
|
||||
return {
|
||||
block,
|
||||
isEmpty: block.length === 0,
|
||||
@@ -149,8 +157,11 @@ export const movePendingToVersion = async (
|
||||
version: string,
|
||||
dateString: string,
|
||||
): Promise<void> => {
|
||||
let content = await ensurePendingSection(filePath, sectionName);
|
||||
const pendingSection = findPendingSection(content, sectionName)!;
|
||||
let content = await readChangelog(filePath);
|
||||
const pendingSection = findPendingSection(content, sectionName);
|
||||
if (!pendingSection) {
|
||||
throw new Error("No pending changelog entries. Nothing to release.");
|
||||
}
|
||||
const pendingBlock = content.slice(pendingSection.bodyStart, pendingSection.end).trim();
|
||||
if (!pendingBlock) {
|
||||
throw new Error("No pending changelog entries. Nothing to release.");
|
||||
@@ -159,7 +170,10 @@ export const movePendingToVersion = async (
|
||||
const renderedHeading = versionHeading
|
||||
.replaceAll("{{version}}", version)
|
||||
.replaceAll("{{date}}", dateString);
|
||||
const nextContent = content.slice(pendingSection.end).replace(/^\n+/, "");
|
||||
content = `${content.slice(0, pendingSection.bodyStart)}\n\n${renderedHeading}\n\n${pendingBlock}\n\n${nextContent}`;
|
||||
const beforePending = content.slice(0, pendingSection.start).trimEnd();
|
||||
const afterPending = content.slice(pendingSection.end).replace(/^\n+/, "").trimEnd();
|
||||
content = [beforePending, renderedHeading, pendingBlock, afterPending]
|
||||
.filter((block) => block.length > 0)
|
||||
.join("\n\n");
|
||||
await writeChangelog(filePath, content);
|
||||
};
|
||||
|
||||
@@ -27,7 +27,8 @@ export async function detectCurrentBranch(): Promise<string> {
|
||||
logger.log('info', `Detected current branch: ${branchName}`);
|
||||
return branchName;
|
||||
} catch (error) {
|
||||
logger.log('warn', `Failed to detect branch: ${error.message}, falling back to "master"`);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logger.log('warn', `Failed to detect branch: ${errorMessage}, falling back to "master"`);
|
||||
return 'master';
|
||||
}
|
||||
}
|
||||
@@ -225,6 +226,7 @@ export async function bumpProjectVersion(
|
||||
|
||||
return newVersion;
|
||||
} catch (error) {
|
||||
throw new Error(`Failed to bump project version: ${error.message}`);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
throw new Error(`Failed to bump project version: ${errorMessage}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,10 @@ export class DiffReporter {
|
||||
change.content,
|
||||
);
|
||||
} catch (error) {
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logger.log(
|
||||
'error',
|
||||
`Failed to generate diff for ${change.path}: ${error.message}`,
|
||||
`Failed to generate diff for ${change.path}: ${errorMessage}`,
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -93,7 +93,8 @@ export class CopyFormatter extends BaseFormatter {
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
logVerbose(`Failed to process pattern ${pattern.from}: ${error.message}`);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logVerbose(`Failed to process pattern ${pattern.from}: ${errorMessage}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,8 @@ export class PackageJsonFormatter extends BaseFormatter {
|
||||
packageJson.pnpm = packageJson.pnpm || {};
|
||||
packageJson.pnpm.overrides = overrides;
|
||||
} catch (error) {
|
||||
logVerbose(`Could not read overrides.json: ${error.message}`);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logVerbose(`Could not read overrides.json: ${errorMessage}`);
|
||||
}
|
||||
|
||||
const newContent = JSON.stringify(packageJson, null, 2);
|
||||
|
||||
@@ -117,7 +117,8 @@ export class TemplatesFormatter extends BaseFormatter {
|
||||
try {
|
||||
renderedFiles = await this.renderTemplate(templateName);
|
||||
} catch (error) {
|
||||
logVerbose(`Failed to render template ${templateName}: ${error.message}`);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logVerbose(`Failed to render template ${templateName}: ${errorMessage}`);
|
||||
return changes;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,8 @@ export class TsconfigFormatter extends BaseFormatter {
|
||||
];
|
||||
}
|
||||
} catch (error) {
|
||||
logVerbose(`Could not get tspublish modules: ${error.message}`);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logVerbose(`Could not get tspublish modules: ${errorMessage}`);
|
||||
}
|
||||
|
||||
tsconfigObject.compilerOptions.paths = { ...existingPaths, ...tspublishPaths };
|
||||
|
||||
@@ -26,7 +26,7 @@ export class Meta {
|
||||
/**
|
||||
* the meta repo data
|
||||
*/
|
||||
public metaRepoData: interfaces.IMetaRepoData;
|
||||
public metaRepoData!: interfaces.IMetaRepoData;
|
||||
public smartshellInstance = new plugins.smartshell.Smartshell({
|
||||
executor: 'bash',
|
||||
});
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import * as plugins from './mod.plugins.js';
|
||||
import * as paths from '../paths.js';
|
||||
|
||||
export let run = (argvArg) => {
|
||||
let projectInfo = new plugins.projectinfo.ProjectInfo(paths.cwd);
|
||||
export let run = async (argvArg) => {
|
||||
let projectInfo = await plugins.projectinfo.ProjectInfo.create(paths.cwd);
|
||||
if (argvArg._[1] === 'ci') {
|
||||
plugins.smartopen.openUrl(
|
||||
`https://gitlab.com/${projectInfo.git.gituser}/${projectInfo.git.gitrepo}/settings/ci_cd`,
|
||||
|
||||
@@ -148,7 +148,8 @@ export class DockerContainer {
|
||||
const result = await this.smartshell.exec(command);
|
||||
return result.exitCode === 0;
|
||||
} catch (error) {
|
||||
logger.log('error', `Failed to run container: ${error.message}`);
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
logger.log('error', `Failed to run container: ${errorMessage}`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -177,7 +178,8 @@ export class DockerContainer {
|
||||
const result = await this.smartshell.exec(`docker logs ${tailFlag} ${containerName}`);
|
||||
return result.stdout;
|
||||
} catch (error) {
|
||||
return `Error getting logs: ${error.message}`;
|
||||
const errorMessage = error instanceof Error ? error.message : String(error);
|
||||
return `Error getting logs: ${errorMessage}`;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,4 +260,4 @@ export class DockerContainer {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ export interface IServiceConfig {
|
||||
|
||||
export class ServiceConfiguration {
|
||||
private configPath: string;
|
||||
private config: IServiceConfig;
|
||||
private config!: IServiceConfig;
|
||||
private docker: DockerContainer;
|
||||
|
||||
constructor() {
|
||||
@@ -515,4 +515,4 @@ export class ServiceConfiguration {
|
||||
logger.log('info', ` 📍 S3 Console: ${s3ConsolePort}`);
|
||||
logger.log('info', ` 📍 Elasticsearch: ${esPort}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,13 +61,15 @@ export class ServiceManager {
|
||||
default: ['mongodb', 'minio', 'elasticsearch']
|
||||
});
|
||||
|
||||
this.enabledServices = response.value || ['mongodb', 'minio', 'elasticsearch'];
|
||||
const enabledServices = response.value || ['mongodb', 'minio', 'elasticsearch'];
|
||||
this.enabledServices = enabledServices;
|
||||
|
||||
// Save to .smartconfig.json
|
||||
await this.saveServiceConfiguration(this.enabledServices);
|
||||
await this.saveServiceConfiguration(enabledServices);
|
||||
} else {
|
||||
this.enabledServices = gitzoneConfig.services;
|
||||
logger.log('info', `🔧 Enabled services: ${this.enabledServices.join(', ')}`);
|
||||
const enabledServices = gitzoneConfig.services as string[];
|
||||
this.enabledServices = enabledServices;
|
||||
logger.log('info', `🔧 Enabled services: ${enabledServices.join(', ')}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -902,10 +904,11 @@ export class ServiceManager {
|
||||
default: currentServices
|
||||
});
|
||||
|
||||
this.enabledServices = response.value || ['mongodb', 'minio', 'elasticsearch'];
|
||||
const enabledServices = response.value || ['mongodb', 'minio', 'elasticsearch'];
|
||||
this.enabledServices = enabledServices;
|
||||
|
||||
// Save to .smartconfig.json
|
||||
await this.saveServiceConfiguration(this.enabledServices);
|
||||
await this.saveServiceConfiguration(enabledServices);
|
||||
|
||||
logger.log('ok', '✅ Service configuration updated');
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ export const isTemplate = async (templateNameArg: string) => {
|
||||
};
|
||||
|
||||
export const getTemplate = async (templateNameArg: string) => {
|
||||
if (isTemplate(templateNameArg)) {
|
||||
if (await isTemplate(templateNameArg)) {
|
||||
const localScafTemplate = new plugins.smartscaf.ScafTemplate(
|
||||
getTemplatePath(templateNameArg),
|
||||
);
|
||||
@@ -50,6 +50,10 @@ export const run = async (argvArg: any) => {
|
||||
}
|
||||
|
||||
const localScafTemplate = await getTemplate(chosenTemplate);
|
||||
if (!localScafTemplate) {
|
||||
logger.log('error', `Template ${chosenTemplate} not available`);
|
||||
return;
|
||||
}
|
||||
await localScafTemplate.askCliForMissingVariables();
|
||||
await localScafTemplate.writeToDisk(paths.cwd);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user