From 4526c8a171dbe40762c116e5b8a404f20131d2b1 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Mon, 7 Jul 2025 23:25:10 +0300 Subject: feat: add comprehensive showcase generation with metadata and images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add --showcase flag to generate project showcases using Claude - Extract repository metadata (languages, commits, LOC, dates, license) - Support image extraction from README files (local and remote) - Add caching with --force flag to regenerate - Add exclude_from_showcase config option - Add standalone showcase mode (--showcase without sync) - Sort projects by recent activity (avg age of last 100 commits) - Output in Gemini Gemtext template format (.gmi.tpl) - Fix backup location fetching when --backup flag not set 🤖 Generated with Claude Code Co-Authored-By: Claude --- internal/sync/sync.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) (limited to 'internal/sync') diff --git a/internal/sync/sync.go b/internal/sync/sync.go index af0feba..85372fa 100644 --- a/internal/sync/sync.go +++ b/internal/sync/sync.go @@ -114,6 +114,49 @@ func (s *Syncer) SyncRepository(repoName string) error { return nil } +// EnsureRepositoryCloned ensures a repository is cloned locally without syncing +// This is used for showcase-only mode +func (s *Syncer) EnsureRepositoryCloned(repoName string) error { + s.repoName = repoName + + // Create work directory if it doesn't exist + if err := os.MkdirAll(s.workDir, 0755); err != nil { + return fmt.Errorf("failed to create work directory: %w", err) + } + + // Check if repository already exists + repoPath := filepath.Join(s.workDir, repoName) + if _, err := os.Stat(repoPath); err == nil { + // Repository exists, nothing to do + fmt.Printf(" Repository %s already exists locally\n", repoName) + return nil + } + + // Repository doesn't exist, clone it + fmt.Printf(" Cloning %s...\n", repoName) + + // Find first non-backup organization to clone from + var sourceOrg *config.Organization + for i := range s.config.Organizations { + if !s.config.Organizations[i].BackupLocation { + sourceOrg = &s.config.Organizations[i] + break + } + } + + if sourceOrg == nil { + return fmt.Errorf("no non-backup organizations configured to clone from") + } + + // Clone the repository + if err := s.cloneRepository(sourceOrg, repoPath); err != nil { + return fmt.Errorf("failed to clone repository: %w", err) + } + + fmt.Printf(" Successfully cloned %s\n", repoName) + return nil +} + // cloneRepository clones a repository from an organization func (s *Syncer) cloneRepository(org *config.Organization, repoPath string) error { // Skip cloning from backup locations @@ -186,8 +229,13 @@ func (s *Syncer) fetchAll() error { // Fetch from each remote for remote := range remotes { - // Skip backup locations - we don't fetch from them + // Skip backup locations if backup is not enabled if org, exists := remotesMap[remote]; exists && org.BackupLocation { + if !s.backupEnabled { + // Silently skip - don't even print a message since backup is not enabled + continue + } + // Even when backup is enabled, we don't fetch from backup locations fmt.Printf("Skipping fetch from backup location %s\n", remote) continue } -- cgit v1.2.3