vendor = (string) $this->argument( 'vendor' ); $this->package = (string) $this->argument( 'package' ); $months = (int) $this->argument( 'months' ); $this->info( 'Checking: ' . sprintf( '%s/%s', $this->vendor, $this->package ) ); $this->info( 'Months: ' . $months ); $payload = Http::get( sprintf( 'https://packagist.org/packages/%s/%s.json', $this->vendor, $this->package ) ); $this->filter = now()->subMonths( $months )->day( 1 )->toDateString(); try { $pkg = new PackagistApiPackagePayload( $payload->json() ); $this->info( 'Found the package. Type: ' . $pkg->type ); $versions = collect( $pkg->versions ?? [] ) ->keys() // Filter actual versions out. ->filter( fn( $version ) => \str_starts_with( $version, 'dev-' ) ) ->sort(); $this->total_branches = $versions->count(); $this->info( sprintf( 'Package has %d branches. Starting to download statistics.', $this->total_branches ) ); $statistics = collect( $versions ) ->mapWithKeys( fn( $branch ) => $this->get_statistics( $branch ) ) ->toArray(); $this->info( 'Downloaded statistics...' ); $this->output_table( $statistics ); $this->output_suggestions( $statistics ); } catch ( \Exception $e ) { $this->error( $e->getMessage(), $e ); } return 0; } private function get_statistics( $branch ) : array { $payload = Http::get( sprintf( 'https://packagist.org/packages/%s/%s/stats/%s.json?average=monthly&from=%s', $this->vendor, $this->package, $branch, $this->filter ) ); $data = collect( $payload->json() ); $labels = collect( $data->get( 'labels', [] ) )->toArray(); $values = collect( $data->get( 'values', [] ) )->flatten()->toArray(); $labels[] = 'Total'; $values[] = array_sum( $values ); return [ $branch => \array_combine( $labels, $values ) ]; } private function output_table( array $statistics ) : void { if ( empty( $statistics ) ) { $this->info( 'No statistics found... Stopping.' ); exit( 0 ); } $tableHeaders = [ '' => 'Branch' ]; $tableBranches = []; foreach ( $statistics as $branch => $stats ) { foreach ( $stats as $m => $v ) { $tableHeaders[ $m ] = (string) $m; $tableBranches[ $branch ][ $branch ] = $branch; $tableBranches[ $branch ][ $m ] = (string) $v; } } $this->line(''); $this->table( $tableHeaders, $tableBranches ); } private function output_suggestions( array $statistics = [] ) : void { $deletable = []; if ( empty( $statistics ) ) { $this->info( 'No statistics to give suggestions for. Quitting...' ); exit( 0 ); } foreach ( $statistics as $k => $values ) { if ( ! empty( $values['Total'] ) ) { continue; } $deletable[ $k ] = $values['Total']; } if ( empty( $deletable ) ) { $this->info( 'No suggestions available. Good job!' ); exit( 0 ); } $keys = array_keys( $deletable ); $branches = collect( $keys )->mapWithKeys( function ( $branch ) { return [ $branch => [ $branch, sprintf( 'https://packagist.org/packages/%s/%s#%s', $this->vendor, $this->package, $branch ), ], ]; } ); $this->line(''); $this->info( sprintf( 'Found %d branches (out of %d total) with no downloads since %s', $branches->count(), $this->total_branches, $this->filter ) ); $this->table( [ 'Branch', 'URL' ], $branches ); } }