UNPKG

repoweaver

Version:

A GitHub App that skillfully weaves multiple templates together to create and update repositories with intelligent merge strategies

218 lines (203 loc) 8.67 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GitHubBootstrapper = void 0; const github_template_manager_1 = require("./github-template-manager"); class GitHubBootstrapper { constructor(client) { this.client = client; this.templateManager = new github_template_manager_1.GitHubTemplateManager(client); } async bootstrap(options) { const result = { success: true, repositoryPath: `${options.targetOwner}/${options.targetRepo}`, templateResults: [], totalFilesProcessed: 0, errors: [] }; try { // Create repository if requested if (options.createRepository) { await this.createRepository(options); } // Process each template for (const template of options.templates) { const templateResult = await this.templateManager.processTemplate(template, options.targetOwner, options.targetRepo, options.excludePatterns, options.mergeStrategy); result.templateResults.push(templateResult); result.totalFilesProcessed += templateResult.filesProcessed; if (!templateResult.success) { result.success = false; result.errors.push(...templateResult.errors); } } // If all templates were processed successfully, create a summary PR if (result.success && result.templateResults.length > 1) { await this.createSummaryPullRequest(options, result); } } catch (error) { result.success = false; result.errors.push(`Bootstrap failed: ${error}`); } return result; } async updateRepository(options) { const result = { success: true, repositoryPath: `${options.targetOwner}/${options.targetRepo}`, templateResults: [], totalFilesProcessed: 0, errors: [] }; try { // Verify repository exists await this.client.getRepository(options.targetOwner, options.targetRepo); // Process templates with merge strategy for (const template of options.templates) { const templateResult = await this.templateManager.processTemplate(template, options.targetOwner, options.targetRepo, options.excludePatterns, options.mergeStrategy || 'merge'); result.templateResults.push(templateResult); result.totalFilesProcessed += templateResult.filesProcessed; if (!templateResult.success) { result.success = false; result.errors.push(...templateResult.errors); } } } catch (error) { result.success = false; result.errors.push(`Update failed: ${error}`); } return result; } async createRepository(options) { try { return await this.client.createRepository(options.targetRepo, options.repositoryDescription, options.privateRepository); } catch (error) { throw new Error(`Failed to create repository: ${error}`); } } async createSummaryPullRequest(options, result) { try { const branch = `boots-strapper-multi-template-${Date.now()}`; await this.client.createBranch(options.targetOwner, options.targetRepo, branch); // Create a summary file const summaryContent = this.generateSummaryContent(options, result); await this.client.createOrUpdateFile(options.targetOwner, options.targetRepo, 'BOOTSTRAP_SUMMARY.md', summaryContent, 'Add bootstrap summary', branch); // Create pull request await this.client.createPullRequest(options.targetOwner, options.targetRepo, `Bootstrap repository with ${options.templates.length} templates`, this.generateMultiTemplatePRBody(options, result), branch, 'main'); } catch (error) { result.errors.push(`Failed to create summary PR: ${error}`); } } generateSummaryContent(options, result) { const timestamp = new Date().toISOString(); return ` # Bootstrap Summary **Repository:** ${options.targetOwner}/${options.targetRepo} **Generated:** ${timestamp} **Total Files Processed:** ${result.totalFilesProcessed} ## Templates Applied ${options.templates.map(template => ` ### ${template.name} - **URL:** ${template.url} - **Branch:** ${template.branch || 'main'} ${template.subDirectory ? `- **Subdirectory:** ${template.subDirectory}` : ''} - **Files Processed:** ${result.templateResults.find(r => r.template.name === template.name)?.filesProcessed || 0} `).join('\n')} ## Configuration - **Merge Strategy:** ${options.mergeStrategy || 'merge'} - **Exclude Patterns:** ${options.excludePatterns?.join(', ') || 'None'} --- *Generated by [RepoWeaver](https://github.com/apps/repoweaver)* `.trim(); } generateMultiTemplatePRBody(options, result) { return ` ## Multi-Template Bootstrap This pull request bootstraps the repository with **${options.templates.length} templates**. **Summary:** - Total files processed: **${result.totalFilesProcessed}** - Templates applied: **${options.templates.length}** - Merge strategy: **${options.mergeStrategy || 'merge'}** **Templates:** ${options.templates.map((template, index) => { const templateResult = result.templateResults[index]; return `${index + 1}. **${template.name}** - ${templateResult.filesProcessed} files`; }).join('\n')} **Pull Requests Created:** ${result.templateResults .filter(r => r.pullRequestNumber) .map(r => `- ${r.template.name}: #${r.pullRequestNumber}`) .join('\n')} See \`BOOTSTRAP_SUMMARY.md\` for detailed information. --- *This PR was automatically generated by [RepoWeaver](https://github.com/apps/repoweaver)* `.trim(); } async getRepositoryTemplates(owner, repo) { try { // Look for RepoWeaver configuration files const configFiles = ['weaver.json', '.weaver.json', '.repoweaver.json']; for (const configFileName of configFiles) { try { const files = await this.client.getRepositoryContents(owner, repo, configFileName); const configFile = files.find(f => f.name === configFileName); if (configFile) { const config = JSON.parse(configFile.content); return config.templates || []; } } catch (error) { // File doesn't exist, try next one continue; } } return []; } catch (error) { return []; } } async getRepositoryConfig(owner, repo) { try { // Look for RepoWeaver configuration files const configFiles = ['weaver.json', '.weaver.json', '.repoweaver.json']; for (const configFileName of configFiles) { try { const files = await this.client.getRepositoryContents(owner, repo, configFileName); const configFile = files.find(f => f.name === configFileName); if (configFile) { const config = JSON.parse(configFile.content); return config; } } catch (error) { // File doesn't exist, try next one continue; } } return null; } catch (error) { return null; } } async saveRepositoryTemplates(owner, repo, templates) { const config = { templates, lastUpdated: new Date().toISOString() }; await this.client.createOrUpdateFile(owner, repo, 'weaver.json', JSON.stringify(config, null, 2), 'Update RepoWeaver configuration'); } async saveRepositoryConfig(owner, repo, config) { const configWithMetadata = { ...config, lastUpdated: new Date().toISOString() }; await this.client.createOrUpdateFile(owner, repo, 'weaver.json', JSON.stringify(configWithMetadata, null, 2), 'Update RepoWeaver configuration'); } } exports.GitHubBootstrapper = GitHubBootstrapper; //# sourceMappingURL=github-bootstrapper.js.map