when( $names = $this->argument('repository'), fn ($q) => $q->whereIn('full_name', $names), ) ->unless( $this->option('force') || $names, // Skip anything refreshed recently so a manual sync is not // immediately redone by the scheduled run. fn ($q) => $q->where(fn ($sub) => $sub ->whereNull('last_synced_at') ->orWhere('last_synced_at', '<', now()->subMinutes((int) config('git.sync_ttl_minutes', 55)))), ) ->get(); if ($repositories->isEmpty()) { $this->components->info('Nothing to sync.'); return self::SUCCESS; } // Running inline gives immediate, readable output — useful when // setting things up or debugging a failing repository. if ($this->option('sync')) { return $this->runInline($git, $repositories); } $repositories->each(fn (Repository $repo) => SyncRepository::dispatch($repo)); $this->components->info("Queued {$repositories->count()} repositories for syncing."); return self::SUCCESS; } /** * @param Collection $repositories */ protected function runInline(GitManager $git, $repositories): int { $failed = 0; foreach ($repositories as $repository) { try { $synced = $git->sync($repository); $this->components->twoColumnDetail( $repository->full_name, sprintf( '%d★ · %d issues · %s', $synced->stars, $synced->goodFirstIssues()->count(), $synced->pushed_at?->diffForHumans() ?? 'never pushed', ), ); } catch (GitException $e) { $failed++; $this->components->twoColumnDetail( $repository->full_name, ''.$e->getMessage().'', ); } } if ($failed > 0) { $this->newLine(); $this->components->warn("{$failed} repository(ies) failed to sync."); return self::FAILURE; } return self::SUCCESS; } }