Skip to content

Instantly share code, notes, and snippets.

@westonplatter
Created June 7, 2025 18:39
Show Gist options
  • Save westonplatter/304cd99a534a14ce2d08555444e582a6 to your computer and use it in GitHub Desktop.
Save westonplatter/304cd99a534a14ce2d08555444e582a6 to your computer and use it in GitHub Desktop.
export function extractTerraformResources(content: string): TerraformResource[] {
logger.info('Starting Terraform resource extraction');
const resources: TerraformResource[] = [];
const lines = content.split('\n');
logger.debug('File processing started', { totalLines: lines.length });
let bracketLevel = 0;
let currentResource: Partial<TerraformResource> | null = null;
let resourceContent: string[] = [];
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const lineNumber = i + 1;
// Track bracket nesting level
const openBrackets = (line.match(/{/g) || []).length;
const closeBrackets = (line.match(/}/g) || []).length;
const oldBracketLevel = bracketLevel;
bracketLevel += openBrackets - closeBrackets;
// Look for resource definitions
const resourceMatch = line.match(/resource\s+"([^"]+)"\s+"([^"]+)"/);
if (resourceMatch) {
logger.info('Found resource definition', {
line: lineNumber,
type: resourceMatch[1],
name: resourceMatch[2]
});
// Save previous resource if exists
if (currentResource && resourceContent.length > 0) {
const completedResource = {
type: currentResource.type!,
name: currentResource.name!,
startLine: currentResource.startLine!,
endLine: lineNumber - 1,
content: resourceContent.join('\n'),
};
logger.debug('Completed previous resource', {
type: completedResource.type,
name: completedResource.name,
startLine: completedResource.startLine,
endLine: completedResource.endLine
});
resources.push(completedResource);
}
// Start new resource
currentResource = {
type: resourceMatch[1],
name: resourceMatch[2],
startLine: lineNumber,
};
resourceContent = [line];
logger.debug('Started tracking new resource', {
type: currentResource.type,
name: currentResource.name
});
continue;
}
// Add lines to current resource
if (currentResource) {
resourceContent.push(line);
// Log bracket level changes for debugging
if (oldBracketLevel !== bracketLevel) {
logger.debug('Bracket level change', {
line: lineNumber,
oldLevel: oldBracketLevel,
newLevel: bracketLevel,
content: line.trim()
});
}
// Check if resource is complete
if (bracketLevel === 0 && line.trim() === '}') {
const completedResource = {
type: currentResource.type!,
name: currentResource.name!,
startLine: currentResource.startLine!,
endLine: lineNumber,
content: resourceContent.join('\n'),
};
logger.debug('Resource complete', {
type: completedResource.type,
name: completedResource.name,
startLine: completedResource.startLine,
endLine: completedResource.endLine,
contentPreview: resourceContent.slice(0, 3).join('\n')
});
resources.push(completedResource);
currentResource = null;
resourceContent = [];
}
}
}
// Handle case where file ends while in resource
if (currentResource && resourceContent.length > 0) {
const completedResource = {
type: currentResource.type!,
name: currentResource.name!,
startLine: currentResource.startLine!,
endLine: lines.length,
content: resourceContent.join('\n'),
};
logger.warn('File ended while in resource', {
type: completedResource.type,
name: completedResource.name,
startLine: completedResource.startLine,
endLine: completedResource.endLine
});
resources.push(completedResource);
}
logger.info('Resource extraction complete', {
totalResources: resources.length,
resourceSummary: resources.map(r => ({
type: r.type,
name: r.name,
lines: `${r.startLine}-${r.endLine}`
}))
});
return resources;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment