From 5fd46886474d88b0ae4f5b728756d535b55d2673 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sun, 14 Jun 2020 11:29:48 +0200 Subject: [PATCH 001/103] Make DEFAULT_CLASSIFIER public --- src/Classifier.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Classifier.php b/src/Classifier.php index d67f9800..942c27d8 100644 --- a/src/Classifier.php +++ b/src/Classifier.php @@ -35,7 +35,7 @@ class Classifier { - private const DEFAULT_CLASSIFIER = [ + public const DEFAULT_CLASSIFIER = [ ControllerClassifier::class, ModelClassifier::class, CommandClassifier::class, From 49290b08cdffb1abe9af55bde20beae099bb1be3 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sun, 14 Jun 2020 11:35:24 +0200 Subject: [PATCH 002/103] Add first collectable Metrics --- src/Contracts/CollectableMetric.php | 13 +++++++++ .../AvailableMetrics/FrameworkVersion.php | 23 ++++++++++++++++ src/Metrics/AvailableMetrics/Metric.php | 27 +++++++++++++++++++ .../AvailableMetrics/ProjectLinesOfCode.php | 23 ++++++++++++++++ .../ProjectLogicalLinesOfCode.php | 23 ++++++++++++++++ 5 files changed, 109 insertions(+) create mode 100644 src/Contracts/CollectableMetric.php create mode 100644 src/Metrics/AvailableMetrics/FrameworkVersion.php create mode 100644 src/Metrics/AvailableMetrics/Metric.php create mode 100644 src/Metrics/AvailableMetrics/ProjectLinesOfCode.php create mode 100644 src/Metrics/AvailableMetrics/ProjectLogicalLinesOfCode.php diff --git a/src/Contracts/CollectableMetric.php b/src/Contracts/CollectableMetric.php new file mode 100644 index 00000000..b93fee4e --- /dev/null +++ b/src/Contracts/CollectableMetric.php @@ -0,0 +1,13 @@ +version(); + } +} diff --git a/src/Metrics/AvailableMetrics/Metric.php b/src/Metrics/AvailableMetrics/Metric.php new file mode 100644 index 00000000..d5a0a3d1 --- /dev/null +++ b/src/Metrics/AvailableMetrics/Metric.php @@ -0,0 +1,27 @@ +project = $project; + } + + public function toArray() + { + return [ + 'type' => $this->type(), + 'name' => $this->name(), + 'value' => $this->value(), + ]; + } +} diff --git a/src/Metrics/AvailableMetrics/ProjectLinesOfCode.php b/src/Metrics/AvailableMetrics/ProjectLinesOfCode.php new file mode 100644 index 00000000..ca5ecd49 --- /dev/null +++ b/src/Metrics/AvailableMetrics/ProjectLinesOfCode.php @@ -0,0 +1,23 @@ +project->statistic()->getLinesOfCode(); + } +} diff --git a/src/Metrics/AvailableMetrics/ProjectLogicalLinesOfCode.php b/src/Metrics/AvailableMetrics/ProjectLogicalLinesOfCode.php new file mode 100644 index 00000000..e97f03b4 --- /dev/null +++ b/src/Metrics/AvailableMetrics/ProjectLogicalLinesOfCode.php @@ -0,0 +1,23 @@ +project->statistic()->getLogicalLinesOfCode(); + } +} From 3b5dfcbd234d6b19da383009ca9ef3b9010dda27 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sun, 14 Jun 2020 11:36:47 +0200 Subject: [PATCH 003/103] Add Scratch Class to demonstrate Metric collection --- src/Metrics/AggregateAndSendToShift.php | 160 ++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 src/Metrics/AggregateAndSendToShift.php diff --git a/src/Metrics/AggregateAndSendToShift.php b/src/Metrics/AggregateAndSendToShift.php new file mode 100644 index 00000000..cd218633 --- /dev/null +++ b/src/Metrics/AggregateAndSendToShift.php @@ -0,0 +1,160 @@ +name(); + }, Classifier::DEFAULT_CLASSIFIER); + + // Group Into Components + $groupedByComponent = $project->classifiedClassesGroupedAndFilteredByComponentNames($coreNames) + ->map(function ($classifiedClasses, $componentName) { + return new Component($componentName, $classifiedClasses); + }); + + $availableCollectableStats = collect([ + FrameworkVersion::class, + ProjectLinesOfCode::class, + ProjectLogicalLinesOfCode::class + ])->map(function ($statClass) use ($project) { + return new $statClass($project); + }); + + + + $aggregatedStatistics = []; + + // Top Level Information about a project + $aggregatedStatistics['project'] = [ + // A UUID which identifies a project + // (maybe store the value in a `.config`-file) + 'id' => Str::uuid()->toString(), + + 'framework' => 'Laravel', // or Lumens + + 'numeric' => [ + [ + 'name' => 'lloc', + 'value' => $project->statistic()->getLogicalLinesOfCode(), + ], + [ + 'name' => 'number_of_classes', + 'value' => $project->statistic()->getNumberOfClasses(), + ], + [ + 'name' => 'number_of_routes', + 'value' => app(NumberOfRoutes::class)->get(), + ], + [ + 'name' => 'number_of_relationships', + 'value' => 12, + ], + [ + 'name' => 'number_of_packages', + 'value' => 0, + ], + [ + 'name' => 'number_of_tests', + 'value' => 10, + ], + [ + 'name' => 'number_of_feature_tests', + 'value' => 7 + ], + [ + 'name' => 'number_of_unit_tests', + 'value' => 3 + ], + ], + 'flags' => [ + [ + 'name' => 'inherits_a_base_controller', + 'value' => true + ], + [ + 'name' => 'inherits_a_base_model', + 'value' => false, + ], + [ + 'name' => 'ungards_all_models', + 'value' => false, + ], + [ + 'name' => 'uses_helpers_or_facades', + 'value' => false, + ], + [ + 'name' => 'controller_request_injection', + 'value' => true, + ], + [ + 'name' => 'schedules_tasks', + 'value' => true, + ], + [ + 'name' => 'validation_vs_form_requests', + 'value' => false, + ], + [ + 'name' => 'realtime_facades', + 'value' => false, + ], + [ + 'name' => 'queues_jobs', + 'value' => true, + ], + [ + 'name' => 'uses_app_models_folder', + 'value' => false, + ], + [ + 'name' => 'uses_domain_structure', + 'value' => false, + ], + [ + 'name' => 'has_additional_psr4_sources', + 'value' => false, + ], + [ + 'name' => 'has_custom_psr4_namespace', + 'value' => true + ], + ] + ]; + + + // Loop through all available Core-Components and record + // - Name + // - Total Number of Classes (eg. 15 Models, 12 Controllers) + + /** @var Component $component */ + foreach ($groupedByComponent as $component) { + $aggregatedStatistics['components'][] = [ + 'name' => $component->name, + 'number_of_classes' => $component->getNumberOfClasses(), + 'number_of_methods' => $component->getNumberOfMethods(), + 'loc' => $component->getLogicalLinesOfCode(), + 'loc_per_method' => $component->getLogicalLinesOfCodePerMethod(), + ]; + } + + $aggregatedStatistics['project']['from_classes'][] = $availableCollectableStats->map->toArray(); + + dd($aggregatedStatistics); + } + +} From ffb4b8eb676582cd0fe0050fc2790b3721255c95 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sun, 14 Jun 2020 11:37:05 +0200 Subject: [PATCH 004/103] Extend StatsListoCommand with --share Option --- src/Console/StatsListCommand.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index c5c38bc0..230fe0c5 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -10,6 +10,7 @@ use Wnx\LaravelStats\Outputs\JsonOutput; use Wnx\LaravelStats\Outputs\AsciiTableOutput; use Wnx\LaravelStats\RejectionStrategies\RejectVendorClasses; +use Wnx\LaravelStats\Metrics\AggregateAndSendToShift; class StatsListCommand extends Command { @@ -18,7 +19,7 @@ class StatsListCommand extends Command * * @var string */ - protected $signature = 'stats {--json : Output the statistics as JSON} {-c|--components= : Comma separated list of components which should be displayed}'; + protected $signature = 'stats {--json : Output the statistics as JSON} {-c|--components= : Comma separated list of components which should be displayed} {--s|share : Share project statistic with Laravel community }'; /** * The console command description. @@ -71,6 +72,12 @@ public function handle() $this->getArrayOfComponentsToDisplay() ); } + + if ($this->option('share') === true) { + if ($this->confirm("To you want to proceed and share your project statistics with the Laravel Community?", true)) { + app(AggregateAndSendToShift::class)->fire($project); + } + } } private function getArrayOfComponentsToDisplay(): array From 075d8056ff49c64118a6ddbef4bc3c961e3cd276 Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Sun, 14 Jun 2020 10:01:19 +0000 Subject: [PATCH 005/103] Apply php-cs-fixer changes --- src/Contracts/CollectableMetric.php | 3 +-- src/Metrics/AggregateAndSendToShift.php | 3 +-- src/Metrics/AvailableMetrics/FrameworkVersion.php | 2 +- src/Metrics/AvailableMetrics/Metric.php | 2 +- src/Metrics/AvailableMetrics/ProjectLinesOfCode.php | 2 +- src/Metrics/AvailableMetrics/ProjectLogicalLinesOfCode.php | 2 +- 6 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Contracts/CollectableMetric.php b/src/Contracts/CollectableMetric.php index b93fee4e..41e1bbe1 100644 --- a/src/Contracts/CollectableMetric.php +++ b/src/Contracts/CollectableMetric.php @@ -1,4 +1,4 @@ - Date: Sat, 20 Jun 2020 14:17:01 +0200 Subject: [PATCH 006/103] Move to different Namespace --- src/Console/StatsListCommand.php | 10 +++++----- .../AggregateAndSendToShift.php | 8 ++++---- .../Metrics}/FrameworkVersion.php | 2 +- .../Metrics}/Metric.php | 2 +- .../Metrics}/ProjectLinesOfCode.php | 2 +- .../Metrics}/ProjectLogicalLinesOfCode.php | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) rename src/{Metrics => ShareableMetrics}/AggregateAndSendToShift.php (95%) rename src/{Metrics/AvailableMetrics => ShareableMetrics/Metrics}/FrameworkVersion.php (87%) rename src/{Metrics/AvailableMetrics => ShareableMetrics/Metrics}/Metric.php (89%) rename src/{Metrics/AvailableMetrics => ShareableMetrics/Metrics}/ProjectLinesOfCode.php (88%) rename src/{Metrics/AvailableMetrics => ShareableMetrics/Metrics}/ProjectLogicalLinesOfCode.php (89%) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 230fe0c5..cb20405d 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -2,15 +2,15 @@ namespace Wnx\LaravelStats\Console; -use Illuminate\Support\Str; -use Wnx\LaravelStats\Project; use Illuminate\Console\Command; +use Illuminate\Support\Str; use Wnx\LaravelStats\ClassesFinder; -use Wnx\LaravelStats\ReflectionClass; -use Wnx\LaravelStats\Outputs\JsonOutput; use Wnx\LaravelStats\Outputs\AsciiTableOutput; +use Wnx\LaravelStats\Outputs\JsonOutput; +use Wnx\LaravelStats\Project; +use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\RejectionStrategies\RejectVendorClasses; -use Wnx\LaravelStats\Metrics\AggregateAndSendToShift; +use Wnx\LaravelStats\ShareableMetrics\AggregateAndSendToShift; class StatsListCommand extends Command { diff --git a/src/Metrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php similarity index 95% rename from src/Metrics/AggregateAndSendToShift.php rename to src/ShareableMetrics/AggregateAndSendToShift.php index 6c0433cc..a9e01f24 100644 --- a/src/Metrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -1,13 +1,13 @@ Date: Sat, 20 Jun 2020 14:20:02 +0200 Subject: [PATCH 007/103] Update Confirm Question in Stats Command --- src/Console/StatsListCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index cb20405d..45f20759 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -74,7 +74,7 @@ public function handle() } if ($this->option('share') === true) { - if ($this->confirm("To you want to proceed and share your project statistics with the Laravel Community?", true)) { + if ($this->confirm("Do you want to share stats from your project with the Laravel Community to stats.laravelshift.com?", true)) { app(AggregateAndSendToShift::class)->fire($project); } } From ab8d41b0343014c1d6d4789cdc434bb11d8f9320 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 15:31:45 +0200 Subject: [PATCH 008/103] Simplify toArray() method on Metric If cast to an array, a Metric should just be a key/value pair. --- src/ShareableMetrics/Metrics/Metric.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/ShareableMetrics/Metrics/Metric.php b/src/ShareableMetrics/Metrics/Metric.php index 5bb18434..544c45cd 100644 --- a/src/ShareableMetrics/Metrics/Metric.php +++ b/src/ShareableMetrics/Metrics/Metric.php @@ -19,9 +19,7 @@ public function __construct(Project $project) public function toArray() { return [ - 'type' => $this->type(), - 'name' => $this->name(), - 'value' => $this->value(), + $this->name() => $this->value() ]; } } From 1f22923e5e5afb8ec5712475da35a156eacf1095 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 15:32:53 +0200 Subject: [PATCH 009/103] Add createProjectFromClasses helper to TestCase --- tests/TestCase.php | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/TestCase.php b/tests/TestCase.php index 12f2f70f..98e931f1 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,9 +3,11 @@ namespace Wnx\LaravelStats\Tests; use Illuminate\Contracts\Http\Kernel; +use Orchestra\Testbench\TestCase as Orchestra; +use Wnx\LaravelStats\Project; +use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\StatsServiceProvider; use Wnx\LaravelStats\Tests\Stubs\HttpKernel; -use Orchestra\Testbench\TestCase as Orchestra; use Wnx\LaravelStats\Tests\Stubs\ServiceProviders\EventServiceProvider; abstract class TestCase extends Orchestra @@ -41,4 +43,21 @@ protected function resolveApplicationHttpKernel($app) { $app->singleton(Kernel::class, HttpKernel::class); } + + /** + * Create a new Project based on the passed FQDNs of Classes + * + * @param array $classes + * + * @return \Wnx\LaravelStats\Project + */ + public function createProjectFromClasses(array $classes = []) + { + $classes = collect($classes) + ->map(function ($class) { + return new ReflectionClass($class); + }); + + return new Project($classes); + } } From d9ba234a92df566e60b6098eed20957f27676381 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 15:33:05 +0200 Subject: [PATCH 010/103] WIP --- .../AggregateAndSendToShift.php | 80 ++++++++++--------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index a9e01f24..910d1ecb 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -6,36 +6,29 @@ use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; use Wnx\LaravelStats\ShareableMetrics\Metrics\FrameworkVersion; +use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; +use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLogicalLinesOfCode; -use Wnx\LaravelStats\Statistics\NumberOfRoutes; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectNumberOfClasses; use Wnx\LaravelStats\ValueObjects\Component; class AggregateAndSendToShift { public function fire(Project $project) { - // Get the Names of "Core"-Components - $coreNames = array_map(function ($classifier) { - return (new $classifier)->name(); - }, Classifier::DEFAULT_CLASSIFIER); - - // Group Into Components - $groupedByComponent = $project->classifiedClassesGroupedAndFilteredByComponentNames($coreNames) - ->map(function ($classifiedClasses, $componentName) { - return new Component($componentName, $classifiedClasses); - }); - - $availableCollectableStats = collect([ + $availableCollectibleStats = collect([ FrameworkVersion::class, + ProjectNumberOfClasses::class, ProjectLinesOfCode::class, - ProjectLogicalLinesOfCode::class + ProjectLogicalLinesOfCode::class, + NumberOfRoutes::class, + NumberOfRelationships::class, ])->map(function ($statClass) use ($project) { return new $statClass($project); }); - $aggregatedStatistics = []; // Top Level Information about a project @@ -47,18 +40,6 @@ public function fire(Project $project) 'framework' => 'Laravel', // or Lumens 'numeric' => [ - [ - 'name' => 'lloc', - 'value' => $project->statistic()->getLogicalLinesOfCode(), - ], - [ - 'name' => 'number_of_classes', - 'value' => $project->statistic()->getNumberOfClasses(), - ], - [ - 'name' => 'number_of_routes', - 'value' => app(NumberOfRoutes::class)->get(), - ], [ 'name' => 'number_of_relationships', 'value' => 12, @@ -136,6 +117,33 @@ public function fire(Project $project) ] ]; + $aggregatedStatistics['project']['from_classes'][] = $availableCollectibleStats->map->toArray(); + + + $componentMetrics = $this->getComponentMetrics($project); + + + + $aggregatedStatistics['project']['numeric'] = array_merge($aggregatedStatistics['project']['numeric'], $componentMetrics); + + dd($aggregatedStatistics); + } + + public function getComponentMetrics(Project $project) + { + // Get the Names of "Core"-Components + $coreNames = array_map(function ($classifier) { + return (new $classifier)->name(); + }, Classifier::DEFAULT_CLASSIFIER); + + // Group Into Components + $groupedByComponent = $project->classifiedClassesGroupedAndFilteredByComponentNames($coreNames) + ->map(function ($classifiedClasses, $componentName) { + return new Component($componentName, $classifiedClasses); + }); + + + $aggregatedStatistics = []; // Loop through all available Core-Components and record // - Name @@ -143,17 +151,15 @@ public function fire(Project $project) /** @var Component $component */ foreach ($groupedByComponent as $component) { - $aggregatedStatistics['components'][] = [ - 'name' => $component->name, - 'number_of_classes' => $component->getNumberOfClasses(), - 'number_of_methods' => $component->getNumberOfMethods(), - 'loc' => $component->getLogicalLinesOfCode(), - 'loc_per_method' => $component->getLogicalLinesOfCodePerMethod(), - ]; - } - $aggregatedStatistics['project']['from_classes'][] = $availableCollectableStats->map->toArray(); + $slug = Str::slug(strtolower($component->name), '_'); - dd($aggregatedStatistics); + $aggregatedStatistics["{$slug}_number_of_classes"] = $component->getNumberOfClasses(); + $aggregatedStatistics["{$slug}_number_of_methods"] = $component->getNumberOfMethods(); + $aggregatedStatistics["{$slug}_loc"] = $component->getLogicalLinesOfCode(); + $aggregatedStatistics["{$slug}_loc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); + } + + return $aggregatedStatistics; } } From 3f2901ca4177533ecf6eb52783430b258751e428 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 15:36:30 +0200 Subject: [PATCH 011/103] Add More Model Stubs --- tests/Stubs/Models/Group.php | 14 ++++++++++++++ tests/Stubs/Models/Post.php | 14 ++++++++++++++ tests/Stubs/Models/User.php | 25 +++++++++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 tests/Stubs/Models/Group.php create mode 100644 tests/Stubs/Models/Post.php create mode 100644 tests/Stubs/Models/User.php diff --git a/tests/Stubs/Models/Group.php b/tests/Stubs/Models/Group.php new file mode 100644 index 00000000..ff848bb4 --- /dev/null +++ b/tests/Stubs/Models/Group.php @@ -0,0 +1,14 @@ +hasMany(User::class); + } +} diff --git a/tests/Stubs/Models/Post.php b/tests/Stubs/Models/Post.php new file mode 100644 index 00000000..61e84583 --- /dev/null +++ b/tests/Stubs/Models/Post.php @@ -0,0 +1,14 @@ +belongsTo(User::class); + } +} diff --git a/tests/Stubs/Models/User.php b/tests/Stubs/Models/User.php new file mode 100644 index 00000000..b408082c --- /dev/null +++ b/tests/Stubs/Models/User.php @@ -0,0 +1,25 @@ +hasMany(Project::class); + } + + public function posts(): HasMany + { + return $this->hasMany(Post::class); + } + + public function group(): BelongsTo + { + return $this->belongsTo(Group::class); + } +} From 45c1cc99da9539af210606b276b5c67fdaa77123 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 15:41:02 +0200 Subject: [PATCH 012/103] Add NumberOfRelationships Metric (WIP) This Metric only yields result, if the relationship methods have a type hint with a Laravel Relationship. If no type hint is added, we can't detect if the method returns a relationship or not. (Or at least I need to dig deeper of what's possible with Reflection) --- .../Metrics/NumberOfRelationships.php | 42 +++++++++++++++++++ .../Metrics/NumberOfRelationshipsTest.php | 38 +++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/NumberOfRelationships.php create mode 100644 tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php diff --git a/src/ShareableMetrics/Metrics/NumberOfRelationships.php b/src/ShareableMetrics/Metrics/NumberOfRelationships.php new file mode 100644 index 00000000..8cfa4c95 --- /dev/null +++ b/src/ShareableMetrics/Metrics/NumberOfRelationships.php @@ -0,0 +1,42 @@ +project + ->classifiedClasses() + ->filter(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->classifier->name() === 'Models'; + }) + ->map(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->reflectionClass->getMethods(); + }) + ->flatten(1) + ->filter(function (\ReflectionMethod $method) { + return $method->hasReturnType(); + }) + ->filter(function (\ReflectionMethod $method) { + return Str::of($method->getReturnType()->getName())->startsWith('Illuminate\Database\Eloquent\Relations'); + }) + ->count(); + } +} diff --git a/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php b/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php new file mode 100644 index 00000000..5ce663d3 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php @@ -0,0 +1,38 @@ +createProjectFromClasses([]); + + $metric = new NumberOfRelationships($project); + + $this->assertEquals(0, $metric->value()); + } + + /** @test */ + public function it_returns_correct_number_of_relationships_in_a_project_for_a_given_project() + { + $project = $this->createProjectFromClasses([ + User::class, + Post::class, + Group::class + ]); + + $metric = new NumberOfRelationships($project); + + $this->assertEquals(5, $metric->value()); + } + +} From c7864de15b10d7c7d803fa7fd426de85d02f8ea4 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 15:52:14 +0200 Subject: [PATCH 013/103] Backfill Tests --- .../Metrics/NumberOfRoutes.php | 24 ++++++++++ .../Metrics/ProjectNumberOfClasses.php | 23 ++++++++++ .../Metrics/FrameworkVersionTest.php | 35 +++++++++++++++ .../Metrics/NumberOfRelationshipsTest.php | 10 +++++ .../Metrics/NumberOfRoutesTest.php | 40 +++++++++++++++++ .../Metrics/ProjectLinesOfCodeTest.php | 42 ++++++++++++++++++ .../Metrics/ProjectLogicalLinesOfCodeTest.php | 43 ++++++++++++++++++ .../Metrics/ProjectNumberOfClassesTest.php | 44 +++++++++++++++++++ 8 files changed, 261 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/NumberOfRoutes.php create mode 100644 src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php create mode 100644 tests/ShareableMetrics/Metrics/FrameworkVersionTest.php create mode 100644 tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php create mode 100644 tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php create mode 100644 tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php create mode 100644 tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php diff --git a/src/ShareableMetrics/Metrics/NumberOfRoutes.php b/src/ShareableMetrics/Metrics/NumberOfRoutes.php new file mode 100644 index 00000000..349d7aa1 --- /dev/null +++ b/src/ShareableMetrics/Metrics/NumberOfRoutes.php @@ -0,0 +1,24 @@ +get(); + } +} diff --git a/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php b/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php new file mode 100644 index 00000000..6b5c417a --- /dev/null +++ b/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php @@ -0,0 +1,23 @@ +project->statistic()->getNumberOfClasses(); + } +} diff --git a/tests/ShareableMetrics/Metrics/FrameworkVersionTest.php b/tests/ShareableMetrics/Metrics/FrameworkVersionTest.php new file mode 100644 index 00000000..1ec9dfac --- /dev/null +++ b/tests/ShareableMetrics/Metrics/FrameworkVersionTest.php @@ -0,0 +1,35 @@ +createProjectFromClasses([]); + + $metric = new FrameworkVersion($project); + + $this->assertEquals('framework_version', $metric->name()); + } + + /** @test */ + public function it_returns_correct_framework_version_in_installed_project() + { + $project = $this->createProjectFromClasses([]); + + $metric = new FrameworkVersion($project); + + $this->assertTrue(Str::of($metric->value())->startsWith('7.')); + } +} diff --git a/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php b/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php index 5ce663d3..fb6bb1bb 100644 --- a/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php +++ b/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php @@ -11,6 +11,16 @@ class NumberOfRelationshipsTest extends TestCase { + /** @test */ + public function it_returns_correct_metric_name() + { + $project = $this->createProjectFromClasses([]); + + $metric = new NumberOfRelationships($project); + + $this->assertEquals('project_number_of_relationships', $metric->name()); + } + /** @test */ public function it_returns_0_if_no_relationships_could_be_found_for_a_given_project() { diff --git a/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php b/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php new file mode 100644 index 00000000..cb832039 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php @@ -0,0 +1,40 @@ +createProjectFromClasses([]); + + $metric = new NumberOfRoutes($project); + + $this->assertEquals('number_of_routes', $metric->name()); + } + + /** @test */ + public function it_returns_correct_number_of_routes_for_the_project() + { + Route::get('users', 'Wnx\LaravelStats\Tests\Stubs\Controllers\UsersController@index'); + Route::get('users/create', 'Wnx\LaravelStats\Tests\Stubs\Controllers\UsersController@create'); + Route::post('users', 'Wnx\LaravelStats\Tests\Stubs\Controllers\UsersController@store'); + Route::get('users/{user}', 'Wnx\LaravelStats\Tests\Stubs\Controllers\UsersController@show'); + + $project = $this->createProjectFromClasses([]); + + $metric = new NumberOfRoutes($project); + + $this->assertEquals(4, $metric->value()); + } +} diff --git a/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php new file mode 100644 index 00000000..939c7260 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php @@ -0,0 +1,42 @@ +createProjectFromClasses([]); + + $metric = new ProjectLinesOfCode($project); + + $this->assertEquals('project_lines_of_code', $metric->name()); + } + + /** @test */ + public function it_returns_the_correct_total_number_lines_of_code_for_the_project() + { + $project = $this->createProjectFromClasses([ + User::class, + UsersController::class, + DemoJob::class, + DemoUnitTest::class, + ]); + + $metric = new ProjectLinesOfCode($project); + + $this->assertEquals(118, $metric->value()); + } +} diff --git a/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php b/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php new file mode 100644 index 00000000..f00f9a98 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php @@ -0,0 +1,43 @@ +createProjectFromClasses([]); + + $metric = new ProjectLogicalLinesOfCode($project); + + $this->assertEquals('project_logical_lines_of_code', $metric->name()); + } + + /** @test */ + public function it_returns_the_correct_total_number_logical_lines_of_code_for_the_project() + { + $project = $this->createProjectFromClasses([ + User::class, + UsersController::class, + DemoJob::class, + DemoUnitTest::class, + ]); + + $metric = new ProjectLogicalLinesOfCode($project); + + $this->assertEquals(11.0, $metric->value()); + } +} diff --git a/tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php b/tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php new file mode 100644 index 00000000..e4c85d38 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php @@ -0,0 +1,44 @@ +createProjectFromClasses([]); + + $metric = new ProjectNumberOfClasses($project); + + $this->assertEquals('project_number_of_classes', $metric->name()); + } + + /** @test */ + public function it_returns_correct_number_of_classes_for_the_given_project() + { + $project = $this->createProjectFromClasses([ + User::class, + UsersController::class, + DemoJob::class, + DemoUnitTest::class, + ]); + + $metric = new ProjectNumberOfClasses($project); + + $this->assertEquals(4, $metric->value()); + } +} From 7a3971f34de40bf956e49e64616767c0c130df4c Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 16:18:02 +0200 Subject: [PATCH 014/103] Reorganize AggregateAndSendToShift --- .../AggregateAndSendToShift.php | 135 ++++-------------- 1 file changed, 28 insertions(+), 107 deletions(-) diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index 910d1ecb..1207230a 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -2,6 +2,7 @@ namespace Wnx\LaravelStats\ShareableMetrics; +use Illuminate\Support\Facades\Http; use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; @@ -11,6 +12,7 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLogicalLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectNumberOfClasses; +use Wnx\LaravelStats\ShareableMetrics\ProjectId; use Wnx\LaravelStats\ValueObjects\Component; class AggregateAndSendToShift @@ -28,138 +30,57 @@ public function fire(Project $project) return new $statClass($project); }); - - $aggregatedStatistics = []; - // Top Level Information about a project - $aggregatedStatistics['project'] = [ - // A UUID which identifies a project - // (maybe store the value in a `.config`-file) - 'id' => Str::uuid()->toString(), - - 'framework' => 'Laravel', // or Lumens - - 'numeric' => [ - [ - 'name' => 'number_of_relationships', - 'value' => 12, - ], - [ - 'name' => 'number_of_packages', - 'value' => 0, - ], - [ - 'name' => 'number_of_tests', - 'value' => 10, - ], - [ - 'name' => 'number_of_feature_tests', - 'value' => 7 - ], - [ - 'name' => 'number_of_unit_tests', - 'value' => 3 - ], - ], - 'flags' => [ - [ - 'name' => 'inherits_a_base_controller', - 'value' => true - ], - [ - 'name' => 'inherits_a_base_model', - 'value' => false, - ], - [ - 'name' => 'ungards_all_models', - 'value' => false, - ], - [ - 'name' => 'uses_helpers_or_facades', - 'value' => false, - ], - [ - 'name' => 'controller_request_injection', - 'value' => true, - ], - [ - 'name' => 'schedules_tasks', - 'value' => true, - ], - [ - 'name' => 'validation_vs_form_requests', - 'value' => false, - ], - [ - 'name' => 'realtime_facades', - 'value' => false, - ], - [ - 'name' => 'queues_jobs', - 'value' => true, - ], - [ - 'name' => 'uses_app_models_folder', - 'value' => false, - ], - [ - 'name' => 'uses_domain_structure', - 'value' => false, - ], - [ - 'name' => 'has_additional_psr4_sources', - 'value' => false, - ], - [ - 'name' => 'has_custom_psr4_namespace', - 'value' => true - ], - ] + $metrics = [ + 'id' => app(ProjectId::class)->get(), + 'framework' => 'Laravel', + 'metrics' => [], ]; - $aggregatedStatistics['project']['from_classes'][] = $availableCollectibleStats->map->toArray(); - - + $projectMetrics = $availableCollectibleStats->map->toArray()->collapse(); $componentMetrics = $this->getComponentMetrics($project); + $metrics['metrics'] = $projectMetrics->merge($componentMetrics)->sortKeys(); - - $aggregatedStatistics['project']['numeric'] = array_merge($aggregatedStatistics['project']['numeric'], $componentMetrics); - - dd($aggregatedStatistics); + $this->sendMetricsToApi($metrics); } - public function getComponentMetrics(Project $project) + protected function getComponentMetrics(Project $project): array { // Get the Names of "Core"-Components - $coreNames = array_map(function ($classifier) { + $coreClassifierNames = array_map(function ($classifier) { return (new $classifier)->name(); }, Classifier::DEFAULT_CLASSIFIER); // Group Into Components - $groupedByComponent = $project->classifiedClassesGroupedAndFilteredByComponentNames($coreNames) + $groupedByComponent = $project->classifiedClassesGroupedAndFilteredByComponentNames($coreClassifierNames) ->map(function ($classifiedClasses, $componentName) { return new Component($componentName, $classifiedClasses); }); - $aggregatedStatistics = []; - - // Loop through all available Core-Components and record - // - Name - // - Total Number of Classes (eg. 15 Models, 12 Controllers) + $metrics = []; /** @var Component $component */ foreach ($groupedByComponent as $component) { - $slug = Str::slug(strtolower($component->name), '_'); - $aggregatedStatistics["{$slug}_number_of_classes"] = $component->getNumberOfClasses(); - $aggregatedStatistics["{$slug}_number_of_methods"] = $component->getNumberOfMethods(); - $aggregatedStatistics["{$slug}_loc"] = $component->getLogicalLinesOfCode(); - $aggregatedStatistics["{$slug}_loc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); + $metrics["{$slug}_number_of_classes"] = $component->getNumberOfClasses(); + $metrics["{$slug}_number_of_methods"] = $component->getNumberOfMethods(); + $metrics["{$slug}_loc"] = $component->getLogicalLinesOfCode(); + $metrics["{$slug}_loc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); } - return $aggregatedStatistics; + return $metrics; + } + + private function sendMetricsToApi(array $payload): void + { + // TODO: Replace with URL to Stats API + $response = Http::post('http://127.0.0.1:8000/collect-stats', $payload); + + if ($response->failed()) { + // TODO: Do something here? + } } } From cabaae82896db09fe79c1a09d901f1ebe7b5fb1f Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 16:20:04 +0200 Subject: [PATCH 015/103] Add ProjectId Class --- src/ShareableMetrics/ProjectId.php | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 src/ShareableMetrics/ProjectId.php diff --git a/src/ShareableMetrics/ProjectId.php b/src/ShareableMetrics/ProjectId.php new file mode 100644 index 00000000..bab37671 --- /dev/null +++ b/src/ShareableMetrics/ProjectId.php @@ -0,0 +1,25 @@ +toString(), function ($projectId) use ($pathToRcFile) { + File::put($pathToRcFile, $projectId); + }); + } + +} From 6d2ba2ef966c1e758efdf3470984739c6bbc4718 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 16:20:18 +0200 Subject: [PATCH 016/103] Remove type from CollectableMetric --- src/Contracts/CollectableMetric.php | 2 -- src/ShareableMetrics/Metrics/FrameworkVersion.php | 5 ----- src/ShareableMetrics/Metrics/NumberOfRelationships.php | 5 ----- src/ShareableMetrics/Metrics/NumberOfRoutes.php | 5 ----- src/ShareableMetrics/Metrics/ProjectLinesOfCode.php | 5 ----- src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php | 5 ----- src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php | 5 ----- 7 files changed, 32 deletions(-) diff --git a/src/Contracts/CollectableMetric.php b/src/Contracts/CollectableMetric.php index 41e1bbe1..fa3e3c14 100644 --- a/src/Contracts/CollectableMetric.php +++ b/src/Contracts/CollectableMetric.php @@ -4,8 +4,6 @@ interface CollectableMetric { - public function type(): string; - public function name(): string; public function value(); diff --git a/src/ShareableMetrics/Metrics/FrameworkVersion.php b/src/ShareableMetrics/Metrics/FrameworkVersion.php index a4272847..610f2686 100644 --- a/src/ShareableMetrics/Metrics/FrameworkVersion.php +++ b/src/ShareableMetrics/Metrics/FrameworkVersion.php @@ -6,11 +6,6 @@ class FrameworkVersion extends Metric implements CollectableMetric { - public function type(): string - { - return 'numeric'; - } - public function name(): string { return 'framework_version'; diff --git a/src/ShareableMetrics/Metrics/NumberOfRelationships.php b/src/ShareableMetrics/Metrics/NumberOfRelationships.php index 8cfa4c95..aae18c0d 100644 --- a/src/ShareableMetrics/Metrics/NumberOfRelationships.php +++ b/src/ShareableMetrics/Metrics/NumberOfRelationships.php @@ -10,11 +10,6 @@ class NumberOfRelationships extends Metric implements CollectableMetric { - public function type(): string - { - return 'numeric'; - } - public function name(): string { return 'project_number_of_relationships'; diff --git a/src/ShareableMetrics/Metrics/NumberOfRoutes.php b/src/ShareableMetrics/Metrics/NumberOfRoutes.php index 349d7aa1..0d9142dd 100644 --- a/src/ShareableMetrics/Metrics/NumberOfRoutes.php +++ b/src/ShareableMetrics/Metrics/NumberOfRoutes.php @@ -7,11 +7,6 @@ class NumberOfRoutes extends Metric implements CollectableMetric { - public function type(): string - { - return 'numeric'; - } - public function name(): string { return 'number_of_routes'; diff --git a/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php b/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php index f761d4d0..50f09c21 100644 --- a/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php +++ b/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php @@ -6,11 +6,6 @@ class ProjectLinesOfCode extends Metric implements CollectableMetric { - public function type(): string - { - return 'numeric'; - } - public function name(): string { return 'project_lines_of_code'; diff --git a/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php b/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php index f7f1cf32..8176e610 100644 --- a/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php +++ b/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php @@ -6,11 +6,6 @@ class ProjectLogicalLinesOfCode extends Metric implements CollectableMetric { - public function type(): string - { - return 'numeric'; - } - public function name(): string { return 'project_logical_lines_of_code'; diff --git a/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php b/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php index 6b5c417a..a2104f5d 100644 --- a/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php +++ b/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php @@ -6,11 +6,6 @@ class ProjectNumberOfClasses extends Metric implements CollectableMetric { - public function type(): string - { - return 'numeric'; - } - public function name(): string { return 'project_number_of_classes'; From 0fdfa28f17281657b50a564d2f29c4b454f490df Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 20 Jun 2020 16:23:42 +0200 Subject: [PATCH 017/103] WIP --- .../AggregateAndSendToShift.php | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index 1207230a..8034d61b 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -19,13 +19,16 @@ class AggregateAndSendToShift { public function fire(Project $project) { - $availableCollectibleStats = collect([ + $availableMetrics = collect([ FrameworkVersion::class, - ProjectNumberOfClasses::class, + NumberOfRelationships::class, + NumberOfRoutes::class, ProjectLinesOfCode::class, ProjectLogicalLinesOfCode::class, - NumberOfRoutes::class, - NumberOfRelationships::class, + ProjectNumberOfClasses::class, + // CodeLogicalLinesOfCode + // TestLogicalLinesOfCode + // CodeToTestRatio ])->map(function ($statClass) use ($project) { return new $statClass($project); }); @@ -37,12 +40,14 @@ public function fire(Project $project) 'metrics' => [], ]; - $projectMetrics = $availableCollectibleStats->map->toArray()->collapse(); + $projectMetrics = $availableMetrics->map->toArray()->collapse(); $componentMetrics = $this->getComponentMetrics($project); $metrics['metrics'] = $projectMetrics->merge($componentMetrics)->sortKeys(); - $this->sendMetricsToApi($metrics); + dd($metrics); + + // $this->sendMetricsToApi($metrics); } protected function getComponentMetrics(Project $project): array @@ -67,8 +72,9 @@ protected function getComponentMetrics(Project $project): array $metrics["{$slug}_number_of_classes"] = $component->getNumberOfClasses(); $metrics["{$slug}_number_of_methods"] = $component->getNumberOfMethods(); - $metrics["{$slug}_loc"] = $component->getLogicalLinesOfCode(); - $metrics["{$slug}_loc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); + $metrics["{$slug}_loc"] = $component->getLinesOfCode(); + $metrics["{$slug}_lloc"] = $component->getLogicalLinesOfCode(); + $metrics["{$slug}_lloc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); } return $metrics; From 34dc731e589331468a86f6566f097adb4c519f32 Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Sat, 20 Jun 2020 14:24:17 +0000 Subject: [PATCH 018/103] Apply php-cs-fixer changes --- src/ShareableMetrics/AggregateAndSendToShift.php | 1 - src/ShareableMetrics/Metrics/NumberOfRelationships.php | 2 -- src/ShareableMetrics/ProjectId.php | 3 +-- tests/ShareableMetrics/Metrics/FrameworkVersionTest.php | 7 +------ .../Metrics/NumberOfRelationshipsTest.php | 4 +--- tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php | 7 +------ tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php | 6 +----- .../Metrics/ProjectLogicalLinesOfCodeTest.php | 7 +------ .../Metrics/ProjectNumberOfClassesTest.php | 8 +------- 9 files changed, 7 insertions(+), 38 deletions(-) diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index 8034d61b..d4b0034b 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -12,7 +12,6 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLogicalLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectNumberOfClasses; -use Wnx\LaravelStats\ShareableMetrics\ProjectId; use Wnx\LaravelStats\ValueObjects\Component; class AggregateAndSendToShift diff --git a/src/ShareableMetrics/Metrics/NumberOfRelationships.php b/src/ShareableMetrics/Metrics/NumberOfRelationships.php index aae18c0d..9f4a5e5b 100644 --- a/src/ShareableMetrics/Metrics/NumberOfRelationships.php +++ b/src/ShareableMetrics/Metrics/NumberOfRelationships.php @@ -3,10 +3,8 @@ namespace Wnx\LaravelStats\ShareableMetrics\Metrics; use Illuminate\Support\Str; -use Wnx\LaravelStats\Classifiers\ModelClassifier; use Wnx\LaravelStats\Contracts\CollectableMetric; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; -use Wnx\LaravelStats\ValueObjects\Component; class NumberOfRelationships extends Metric implements CollectableMetric { diff --git a/src/ShareableMetrics/ProjectId.php b/src/ShareableMetrics/ProjectId.php index bab37671..ae15ecfa 100644 --- a/src/ShareableMetrics/ProjectId.php +++ b/src/ShareableMetrics/ProjectId.php @@ -1,4 +1,4 @@ -assertEquals(5, $metric->value()); } - } diff --git a/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php b/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php index cb832039..98773c7d 100644 --- a/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php +++ b/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php @@ -1,14 +1,9 @@ - Date: Tue, 23 Jun 2020 20:50:28 +0200 Subject: [PATCH 019/103] Update Keys for classes and methods --- src/ShareableMetrics/AggregateAndSendToShift.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index d4b0034b..ca683eab 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -69,8 +69,8 @@ protected function getComponentMetrics(Project $project): array foreach ($groupedByComponent as $component) { $slug = Str::slug(strtolower($component->name), '_'); - $metrics["{$slug}_number_of_classes"] = $component->getNumberOfClasses(); - $metrics["{$slug}_number_of_methods"] = $component->getNumberOfMethods(); + $metrics["{$slug}"] = $component->getNumberOfClasses(); + $metrics["{$slug}_methods"] = $component->getNumberOfMethods(); $metrics["{$slug}_loc"] = $component->getLinesOfCode(); $metrics["{$slug}_lloc"] = $component->getLogicalLinesOfCode(); $metrics["{$slug}_lloc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); From 50f9375fe2353cfa2b300331a3a7a0b70c0374f8 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 23 Jun 2020 20:51:35 +0200 Subject: [PATCH 020/103] Remove FrameworkVersion Metric --- .../AggregateAndSendToShift.php | 3 -- .../Metrics/FrameworkVersion.php | 18 ----------- .../Metrics/FrameworkVersionTest.php | 30 ------------------- 3 files changed, 51 deletions(-) delete mode 100644 src/ShareableMetrics/Metrics/FrameworkVersion.php delete mode 100644 tests/ShareableMetrics/Metrics/FrameworkVersionTest.php diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index ca683eab..f98cfe5d 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -6,7 +6,6 @@ use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; -use Wnx\LaravelStats\ShareableMetrics\Metrics\FrameworkVersion; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; @@ -19,7 +18,6 @@ class AggregateAndSendToShift public function fire(Project $project) { $availableMetrics = collect([ - FrameworkVersion::class, NumberOfRelationships::class, NumberOfRoutes::class, ProjectLinesOfCode::class, @@ -35,7 +33,6 @@ public function fire(Project $project) // Top Level Information about a project $metrics = [ 'id' => app(ProjectId::class)->get(), - 'framework' => 'Laravel', 'metrics' => [], ]; diff --git a/src/ShareableMetrics/Metrics/FrameworkVersion.php b/src/ShareableMetrics/Metrics/FrameworkVersion.php deleted file mode 100644 index 610f2686..00000000 --- a/src/ShareableMetrics/Metrics/FrameworkVersion.php +++ /dev/null @@ -1,18 +0,0 @@ -version(); - } -} diff --git a/tests/ShareableMetrics/Metrics/FrameworkVersionTest.php b/tests/ShareableMetrics/Metrics/FrameworkVersionTest.php deleted file mode 100644 index e5436ff9..00000000 --- a/tests/ShareableMetrics/Metrics/FrameworkVersionTest.php +++ /dev/null @@ -1,30 +0,0 @@ -createProjectFromClasses([]); - - $metric = new FrameworkVersion($project); - - $this->assertEquals('framework_version', $metric->name()); - } - - /** @test */ - public function it_returns_correct_framework_version_in_installed_project() - { - $project = $this->createProjectFromClasses([]); - - $metric = new FrameworkVersion($project); - - $this->assertTrue(Str::of($metric->value())->startsWith('7.')); - } -} From c8b9bc54a99172dfdbef1dfdd2559172b8fbeede Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 23 Jun 2020 21:10:50 +0200 Subject: [PATCH 021/103] Add NumberOfPackages --- .../AggregateAndSendToShift.php | 7 +++- .../Metrics/NumberOfPackages.php | 25 ++++++++++++++ .../Metrics/NumberOfPackagesTest.php | 34 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) create mode 100644 src/ShareableMetrics/Metrics/NumberOfPackages.php create mode 100644 tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index f98cfe5d..386c68b5 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -2,10 +2,12 @@ namespace Wnx\LaravelStats\ShareableMetrics; +use Composer\Composer; use Illuminate\Support\Facades\Http; use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; +use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; @@ -18,6 +20,7 @@ class AggregateAndSendToShift public function fire(Project $project) { $availableMetrics = collect([ + NumberOfPackages::class, NumberOfRelationships::class, NumberOfRoutes::class, ProjectLinesOfCode::class, @@ -32,7 +35,7 @@ public function fire(Project $project) // Top Level Information about a project $metrics = [ - 'id' => app(ProjectId::class)->get(), + 'project' => app(ProjectId::class)->get(), 'metrics' => [], ]; @@ -41,6 +44,8 @@ public function fire(Project $project) $metrics['metrics'] = $projectMetrics->merge($componentMetrics)->sortKeys(); + + dd($metrics); // $this->sendMetricsToApi($metrics); diff --git a/src/ShareableMetrics/Metrics/NumberOfPackages.php b/src/ShareableMetrics/Metrics/NumberOfPackages.php new file mode 100644 index 00000000..da3cf46c --- /dev/null +++ b/src/ShareableMetrics/Metrics/NumberOfPackages.php @@ -0,0 +1,25 @@ +createProjectFromClasses([]); + + $metric = new NumberOfPackages($project); + + $this->assertEquals('number_of_packages', $metric->name()); + } + + /** @test */ + public function it_returns_the_correct_total_number_lines_of_code_for_the_project() + { + $project = $this->createProjectFromClasses([]); + + $metric = new NumberOfPackages($project); + + $this->assertEquals(2, $metric->value()); + } +} From 916528553db9debbe0d818a6a8dc7f307607c6f3 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 23 Jun 2020 21:11:41 +0200 Subject: [PATCH 022/103] Hardcode ProjectId for now --- src/ShareableMetrics/ProjectId.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ShareableMetrics/ProjectId.php b/src/ShareableMetrics/ProjectId.php index ae15ecfa..e8eed14b 100644 --- a/src/ShareableMetrics/ProjectId.php +++ b/src/ShareableMetrics/ProjectId.php @@ -11,6 +11,8 @@ class ProjectId public function get(): string { + return 'stefanzweifel/laravel-stats'; + $pathToRcFile = base_path(self::RC_FILE); if (File::exists($pathToRcFile)) { From ad80136ae0d8ae0ce01841fa08b187587a2f9aff Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Tue, 23 Jun 2020 19:12:07 +0000 Subject: [PATCH 023/103] Apply php-cs-fixer changes --- src/ShareableMetrics/AggregateAndSendToShift.php | 1 - src/ShareableMetrics/Metrics/NumberOfPackages.php | 2 +- tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php | 5 ----- 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index 386c68b5..0da2eb6e 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -2,7 +2,6 @@ namespace Wnx\LaravelStats\ShareableMetrics; -use Composer\Composer; use Illuminate\Support\Facades\Http; use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; diff --git a/src/ShareableMetrics/Metrics/NumberOfPackages.php b/src/ShareableMetrics/Metrics/NumberOfPackages.php index da3cf46c..1ce3dc9f 100644 --- a/src/ShareableMetrics/Metrics/NumberOfPackages.php +++ b/src/ShareableMetrics/Metrics/NumberOfPackages.php @@ -20,6 +20,6 @@ public function value() $dependencies = Arr::get($composerJson, 'require', []); $devDependencies = Arr::get($composerJson, 'require-dev', []); - return count($dependencies) + count ($devDependencies); + return count($dependencies) + count($devDependencies); } } diff --git a/tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php b/tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php index 991cee80..d29df3f7 100644 --- a/tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php +++ b/tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php @@ -3,11 +3,6 @@ namespace Wnx\LaravelStats\Tests\ShareableMetrics\Metrics; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfPackages; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; -use Wnx\LaravelStats\Tests\Stubs\Controllers\UsersController; -use Wnx\LaravelStats\Tests\Stubs\Jobs\DemoJob; -use Wnx\LaravelStats\Tests\Stubs\Models\User; -use Wnx\LaravelStats\Tests\Stubs\Tests\DemoUnitTest; use Wnx\LaravelStats\Tests\TestCase; class NumberOfPackagesTest extends TestCase From fbcdbe72158422db5e5f36df1825132d02b43164 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 24 Jun 2020 20:25:58 +0200 Subject: [PATCH 024/103] Update some metric names --- src/ShareableMetrics/Metrics/NumberOfPackages.php | 7 +++++-- src/ShareableMetrics/Metrics/NumberOfRelationships.php | 2 +- src/ShareableMetrics/Metrics/NumberOfRoutes.php | 2 +- src/ShareableMetrics/Metrics/ProjectLinesOfCode.php | 2 +- src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php | 2 +- src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php | 2 +- 6 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/ShareableMetrics/Metrics/NumberOfPackages.php b/src/ShareableMetrics/Metrics/NumberOfPackages.php index 1ce3dc9f..5caa24df 100644 --- a/src/ShareableMetrics/Metrics/NumberOfPackages.php +++ b/src/ShareableMetrics/Metrics/NumberOfPackages.php @@ -10,7 +10,7 @@ class NumberOfPackages extends Metric implements CollectableMetric { public function name(): string { - return 'number_of_packages'; + return 'packages'; } public function value() @@ -20,6 +20,9 @@ public function value() $dependencies = Arr::get($composerJson, 'require', []); $devDependencies = Arr::get($composerJson, 'require-dev', []); - return count($dependencies) + count($devDependencies); + return [ + 'require' => $dependencies, + 'require-dev' => $devDependencies, + ]; } } diff --git a/src/ShareableMetrics/Metrics/NumberOfRelationships.php b/src/ShareableMetrics/Metrics/NumberOfRelationships.php index 9f4a5e5b..aa79cb6f 100644 --- a/src/ShareableMetrics/Metrics/NumberOfRelationships.php +++ b/src/ShareableMetrics/Metrics/NumberOfRelationships.php @@ -10,7 +10,7 @@ class NumberOfRelationships extends Metric implements CollectableMetric { public function name(): string { - return 'project_number_of_relationships'; + return 'models_relationships'; } public function value() diff --git a/src/ShareableMetrics/Metrics/NumberOfRoutes.php b/src/ShareableMetrics/Metrics/NumberOfRoutes.php index 0d9142dd..7b7e262e 100644 --- a/src/ShareableMetrics/Metrics/NumberOfRoutes.php +++ b/src/ShareableMetrics/Metrics/NumberOfRoutes.php @@ -9,7 +9,7 @@ class NumberOfRoutes extends Metric implements CollectableMetric { public function name(): string { - return 'number_of_routes'; + return 'routes'; } public function value() diff --git a/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php b/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php index 50f09c21..c1812ca8 100644 --- a/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php +++ b/src/ShareableMetrics/Metrics/ProjectLinesOfCode.php @@ -8,7 +8,7 @@ class ProjectLinesOfCode extends Metric implements CollectableMetric { public function name(): string { - return 'project_lines_of_code'; + return 'loc'; } public function value() diff --git a/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php b/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php index 8176e610..9cc9c38e 100644 --- a/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php +++ b/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCode.php @@ -8,7 +8,7 @@ class ProjectLogicalLinesOfCode extends Metric implements CollectableMetric { public function name(): string { - return 'project_logical_lines_of_code'; + return 'lloc'; } public function value() diff --git a/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php b/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php index a2104f5d..317d525b 100644 --- a/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php +++ b/src/ShareableMetrics/Metrics/ProjectNumberOfClasses.php @@ -8,7 +8,7 @@ class ProjectNumberOfClasses extends Metric implements CollectableMetric { public function name(): string { - return 'project_number_of_classes'; + return 'classes'; } public function value() From 1aaaaf9e9b4faf70d19c368f7f58f409c14e9efb Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 24 Jun 2020 20:26:21 +0200 Subject: [PATCH 025/103] WIP --- src/Console/StatsListCommand.php | 6 ++ .../AggregateAndSendToShift.php | 70 +------------- src/ShareableMetrics/CollectMetrics.php | 95 +++++++++++++++++++ src/ShareableMetrics/SendToLaravelShift.php | 32 +++++++ 4 files changed, 137 insertions(+), 66 deletions(-) create mode 100644 src/ShareableMetrics/CollectMetrics.php create mode 100644 src/ShareableMetrics/SendToLaravelShift.php diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 45f20759..9c577c29 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -74,6 +74,12 @@ public function handle() } if ($this->option('share') === true) { + + // TODO: Collect the Metrics + // TODO: Get Project Name from local Git Repo + // TODO: Show Collected Metrics to User + // TODO: Ask user to confirm the project name + if ($this->confirm("Do you want to share stats from your project with the Laravel Community to stats.laravelshift.com?", true)) { app(AggregateAndSendToShift::class)->fire($project); } diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php index 0da2eb6e..411447c7 100644 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ b/src/ShareableMetrics/AggregateAndSendToShift.php @@ -1,10 +1,11 @@ -map(function ($statClass) use ($project) { - return new $statClass($project); - }); - - // Top Level Information about a project - $metrics = [ - 'project' => app(ProjectId::class)->get(), - 'metrics' => [], - ]; - - $projectMetrics = $availableMetrics->map->toArray()->collapse(); - $componentMetrics = $this->getComponentMetrics($project); - - $metrics['metrics'] = $projectMetrics->merge($componentMetrics)->sortKeys(); - + $metrics = app(CollectMetrics::class)->get($project); dd($metrics); - // $this->sendMetricsToApi($metrics); - } - - protected function getComponentMetrics(Project $project): array - { - // Get the Names of "Core"-Components - $coreClassifierNames = array_map(function ($classifier) { - return (new $classifier)->name(); - }, Classifier::DEFAULT_CLASSIFIER); - - // Group Into Components - $groupedByComponent = $project->classifiedClassesGroupedAndFilteredByComponentNames($coreClassifierNames) - ->map(function ($classifiedClasses, $componentName) { - return new Component($componentName, $classifiedClasses); - }); - - - $metrics = []; - - /** @var Component $component */ - foreach ($groupedByComponent as $component) { - $slug = Str::slug(strtolower($component->name), '_'); - - $metrics["{$slug}"] = $component->getNumberOfClasses(); - $metrics["{$slug}_methods"] = $component->getNumberOfMethods(); - $metrics["{$slug}_loc"] = $component->getLinesOfCode(); - $metrics["{$slug}_lloc"] = $component->getLogicalLinesOfCode(); - $metrics["{$slug}_lloc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); - } - - return $metrics; + app(SendToLaravelShift::class)->send($metrics); } - private function sendMetricsToApi(array $payload): void - { - // TODO: Replace with URL to Stats API - $response = Http::post('http://127.0.0.1:8000/collect-stats', $payload); - - if ($response->failed()) { - // TODO: Do something here? - } - } } diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php new file mode 100644 index 00000000..c533b215 --- /dev/null +++ b/src/ShareableMetrics/CollectMetrics.php @@ -0,0 +1,95 @@ +map(function ($statClass) use ($project) { + return new $statClass($project); + }); + + // Top Level Information about a project + $metrics = [ + 'project' => app(ProjectId::class)->get(), + 'metrics' => [], + ]; + + $projectMetrics = $availableMetrics->map->toArray()->collapse(); + $componentMetrics = $this->getComponentMetrics($project); + + $metrics['metrics'] = $projectMetrics->merge($componentMetrics)->sortKeys(); + + + return $metrics; + } + + + protected function getComponentMetrics(Project $project): array + { + // Get the Names of "Core"-Components + $coreClassifierNames = array_map(function ($classifier) { + return (new $classifier)->name(); + }, Classifier::DEFAULT_CLASSIFIER); + + // Group Into Components + $groupedByComponent = $project->classifiedClassesGroupedAndFilteredByComponentNames($coreClassifierNames) + ->map(function ($classifiedClasses, $componentName) { + return new Component($componentName, $classifiedClasses); + }); + + + $metrics = []; + + /** @var Component $component */ + foreach ($groupedByComponent as $component) { + $slug = Str::slug(strtolower($component->name), '_'); + + $metrics["{$slug}"] = $component->getNumberOfClasses(); + $metrics["{$slug}_methods"] = $component->getNumberOfMethods(); + $metrics["{$slug}_loc"] = $component->getLinesOfCode(); + $metrics["{$slug}_lloc"] = $component->getLogicalLinesOfCode(); + $metrics["{$slug}_lloc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); + } + + + // TODO: After collection the metrics, collapse the browserkit, dusk and phpunit values into "tests" + // $tests = [ + // 'BrowserKit Tests', + // 'DuskTests', + // 'PHPUnit Tests' + // ]; + + // if (in_array($component->name, $tests)) { + // $slug = 'tests'; + // } else { + // $slug = Str::slug(strtolower($component->name), '_'); + // } + + return $metrics; + } + +} diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php new file mode 100644 index 00000000..8bf5a194 --- /dev/null +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -0,0 +1,32 @@ + $payload['project'], + 'metrics' => $payload['metrics']->toArray() + ]; + + info(json_encode($httpPayload)); + + // TODO: Replace with URL to Stats API + $response = Http::post('https://laravelshift.com/api/stat', $httpPayload); + + dd( + $response->status(), + $response->json(), + $response->body() + ); + + if ($response->failed()) { + dd($response->json()); + } + } + +} From 0f90f2dee8efacea67b64dc4e202a938986ba6dd Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 24 Jun 2020 20:51:15 +0200 Subject: [PATCH 026/103] Add MetricsCollection --- src/ShareableMetrics/MetricsCollection.php | 23 ++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 src/ShareableMetrics/MetricsCollection.php diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php new file mode 100644 index 00000000..511cbff8 --- /dev/null +++ b/src/ShareableMetrics/MetricsCollection.php @@ -0,0 +1,23 @@ +items['metrics']; + + $metrics = $metrics->map(function ($metric) { + if (is_array($metric)) { + return json_encode($metric, JSON_PRETTY_PRINT); + } + + return $metric; + }); + + return $metrics->keys()->zip($metrics)->toArray(); + } +} From c0795acf2fee0b897b18ddaf57ab5431df10b3e5 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 24 Jun 2020 20:51:40 +0200 Subject: [PATCH 027/103] Display Collected Metrics in Console --- src/Console/StatsListCommand.php | 13 ++++++-- .../AggregateAndSendToShift.php | 30 ------------------- src/ShareableMetrics/CollectMetrics.php | 4 ++- src/ShareableMetrics/MetricsCollection.php | 6 +++- src/ShareableMetrics/SendToLaravelShift.php | 5 ++-- 5 files changed, 22 insertions(+), 36 deletions(-) delete mode 100644 src/ShareableMetrics/AggregateAndSendToShift.php diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 9c577c29..5d6b44b4 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -11,6 +11,8 @@ use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\RejectionStrategies\RejectVendorClasses; use Wnx\LaravelStats\ShareableMetrics\AggregateAndSendToShift; +use Wnx\LaravelStats\ShareableMetrics\CollectMetrics; +use Wnx\LaravelStats\ShareableMetrics\SendToLaravelShift; class StatsListCommand extends Command { @@ -80,8 +82,15 @@ public function handle() // TODO: Show Collected Metrics to User // TODO: Ask user to confirm the project name - if ($this->confirm("Do you want to share stats from your project with the Laravel Community to stats.laravelshift.com?", true)) { - app(AggregateAndSendToShift::class)->fire($project); + $metrics = app(CollectMetrics::class)->get($project); + + $this->table( + ['Name', 'Value'], + $metrics->toAsciiTableFormat() + ); + + if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { + // app(SendToLaravelShift::class)->send($metrics); } } } diff --git a/src/ShareableMetrics/AggregateAndSendToShift.php b/src/ShareableMetrics/AggregateAndSendToShift.php deleted file mode 100644 index 411447c7..00000000 --- a/src/ShareableMetrics/AggregateAndSendToShift.php +++ /dev/null @@ -1,30 +0,0 @@ -get($project); - - dd($metrics); - - app(SendToLaravelShift::class)->send($metrics); - } - -} diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index c533b215..1f3f8e7e 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -5,12 +5,14 @@ use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; +use Wnx\LaravelStats\ShareableMetrics\MetricsCollection; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLogicalLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectNumberOfClasses; +use Wnx\LaravelStats\ShareableMetrics\MetrisCollection; use Wnx\LaravelStats\ShareableMetrics\ProjectId; use Wnx\LaravelStats\ValueObjects\Component; @@ -44,7 +46,7 @@ public function get(Project $project) $metrics['metrics'] = $projectMetrics->merge($componentMetrics)->sortKeys(); - return $metrics; + return new MetricsCollection($metrics); } diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php index 511cbff8..a2003ce7 100644 --- a/src/ShareableMetrics/MetricsCollection.php +++ b/src/ShareableMetrics/MetricsCollection.php @@ -18,6 +18,10 @@ public function toAsciiTableFormat(): array return $metric; }); - return $metrics->keys()->zip($metrics)->toArray(); + return $metrics + ->keys() + ->zip($metrics) + ->push(['project', $this->items['project']]) + ->toArray(); } } diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index 8bf5a194..ab9f99a9 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -16,11 +16,12 @@ public function send(array $payload): void info(json_encode($httpPayload)); // TODO: Replace with URL to Stats API - $response = Http::post('https://laravelshift.com/api/stat', $httpPayload); + $response = Http::withHeaders([ + 'Accept' => 'application/json' + ])->post('https://laravelshift.com/api/stat', $httpPayload); dd( $response->status(), - $response->json(), $response->body() ); From 72eeb2fa2bf681cb0f4af27440a22b6fb8a7717e Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Wed, 24 Jun 2020 18:54:27 +0000 Subject: [PATCH 028/103] Apply php-cs-fixer changes --- src/Console/StatsListCommand.php | 1 - src/ShareableMetrics/CollectMetrics.php | 6 +----- src/ShareableMetrics/MetricsCollection.php | 2 +- src/ShareableMetrics/SendToLaravelShift.php | 3 +-- 4 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 5d6b44b4..8cc647b3 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -10,7 +10,6 @@ use Wnx\LaravelStats\Project; use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\RejectionStrategies\RejectVendorClasses; -use Wnx\LaravelStats\ShareableMetrics\AggregateAndSendToShift; use Wnx\LaravelStats\ShareableMetrics\CollectMetrics; use Wnx\LaravelStats\ShareableMetrics\SendToLaravelShift; diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 1f3f8e7e..ad7752a4 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -1,19 +1,16 @@ -json()); } } - } From ad43a21ddf3f6cabae5b83bab66722910946915d Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 27 Jun 2020 15:11:58 +0200 Subject: [PATCH 029/103] Update Tests --- src/ShareableMetrics/CollectMetrics.php | 5 ++- ...erOfPackages.php => InstalledPackages.php} | 10 ++--- .../Metrics/InstalledPackagesTest.php | 42 +++++++++++++++++++ .../Metrics/NumberOfPackagesTest.php | 29 ------------- .../Metrics/NumberOfRelationshipsTest.php | 2 +- .../Metrics/NumberOfRoutesTest.php | 2 +- .../Metrics/ProjectLinesOfCodeTest.php | 2 +- .../Metrics/ProjectLogicalLinesOfCodeTest.php | 2 +- .../Metrics/ProjectNumberOfClassesTest.php | 2 +- 9 files changed, 55 insertions(+), 41 deletions(-) rename src/ShareableMetrics/Metrics/{NumberOfPackages.php => InstalledPackages.php} (59%) create mode 100644 tests/ShareableMetrics/Metrics/InstalledPackagesTest.php delete mode 100644 tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index ad7752a4..1adffdb3 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -5,7 +5,8 @@ use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; -use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfPackages; +use Wnx\LaravelStats\ShareableMetrics\MetricsCollection; +use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; @@ -18,7 +19,7 @@ class CollectMetrics public function get(Project $project) { $availableMetrics = collect([ - NumberOfPackages::class, + InstalledPackages::class, NumberOfRelationships::class, NumberOfRoutes::class, ProjectLinesOfCode::class, diff --git a/src/ShareableMetrics/Metrics/NumberOfPackages.php b/src/ShareableMetrics/Metrics/InstalledPackages.php similarity index 59% rename from src/ShareableMetrics/Metrics/NumberOfPackages.php rename to src/ShareableMetrics/Metrics/InstalledPackages.php index 5caa24df..2ccb280a 100644 --- a/src/ShareableMetrics/Metrics/NumberOfPackages.php +++ b/src/ShareableMetrics/Metrics/InstalledPackages.php @@ -6,7 +6,7 @@ use Illuminate\Support\Facades\File; use Wnx\LaravelStats\Contracts\CollectableMetric; -class NumberOfPackages extends Metric implements CollectableMetric +class InstalledPackages extends Metric implements CollectableMetric { public function name(): string { @@ -17,12 +17,12 @@ public function value() { $composerJson = json_decode(File::get(base_path('composer.json')), true); - $dependencies = Arr::get($composerJson, 'require', []); - $devDependencies = Arr::get($composerJson, 'require-dev', []); + $packages = Arr::get($composerJson, 'require', []); + $devPackages = Arr::get($composerJson, 'require-dev', []); return [ - 'require' => $dependencies, - 'require-dev' => $devDependencies, + 'require' => $packages, + 'require-dev' => $devPackages, ]; } } diff --git a/tests/ShareableMetrics/Metrics/InstalledPackagesTest.php b/tests/ShareableMetrics/Metrics/InstalledPackagesTest.php new file mode 100644 index 00000000..901d608b --- /dev/null +++ b/tests/ShareableMetrics/Metrics/InstalledPackagesTest.php @@ -0,0 +1,42 @@ +createProjectFromClasses([]); + + $metric = new InstalledPackages($project); + + $this->assertEquals('packages', $metric->name()); + } + + /** @test */ + public function it_returns_array_of_installed_packages_for_the_project() + { + $project = $this->createProjectFromClasses([]); + + $metric = new InstalledPackages($project); + + $value = $metric->value(); + + $this->assertIsArray($value); + $this->assertArrayHasKey('require', $value); + $this->assertArrayHasKey('require-dev', $value); + + $this->assertEquals([ + 'require' => [ + 'laravel/framework' => '~5.0' + ], + 'require-dev' => [ + 'phpunit/phpunit' => '~4.0' + ] + ], $value); + } +} diff --git a/tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php b/tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php deleted file mode 100644 index d29df3f7..00000000 --- a/tests/ShareableMetrics/Metrics/NumberOfPackagesTest.php +++ /dev/null @@ -1,29 +0,0 @@ -createProjectFromClasses([]); - - $metric = new NumberOfPackages($project); - - $this->assertEquals('number_of_packages', $metric->name()); - } - - /** @test */ - public function it_returns_the_correct_total_number_lines_of_code_for_the_project() - { - $project = $this->createProjectFromClasses([]); - - $metric = new NumberOfPackages($project); - - $this->assertEquals(2, $metric->value()); - } -} diff --git a/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php b/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php index 81d327d5..55ed8682 100644 --- a/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php +++ b/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php @@ -17,7 +17,7 @@ public function it_returns_correct_metric_name() $metric = new NumberOfRelationships($project); - $this->assertEquals('project_number_of_relationships', $metric->name()); + $this->assertEquals('models_relationships', $metric->name()); } /** @test */ diff --git a/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php b/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php index 98773c7d..88a042c8 100644 --- a/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php +++ b/tests/ShareableMetrics/Metrics/NumberOfRoutesTest.php @@ -15,7 +15,7 @@ public function it_returns_correct_metric_name() $metric = new NumberOfRoutes($project); - $this->assertEquals('number_of_routes', $metric->name()); + $this->assertEquals('routes', $metric->name()); } /** @test */ diff --git a/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php index 1273e84b..e4dcc3ce 100644 --- a/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php +++ b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php @@ -18,7 +18,7 @@ public function it_returns_correct_metric_name() $metric = new ProjectLinesOfCode($project); - $this->assertEquals('project_lines_of_code', $metric->name()); + $this->assertEquals('loc', $metric->name()); } /** @test */ diff --git a/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php b/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php index b037b756..0bba2012 100644 --- a/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php +++ b/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php @@ -18,7 +18,7 @@ public function it_returns_correct_metric_name() $metric = new ProjectLogicalLinesOfCode($project); - $this->assertEquals('project_logical_lines_of_code', $metric->name()); + $this->assertEquals('lloc', $metric->name()); } /** @test */ diff --git a/tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php b/tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php index 83d51b8b..8d7b8994 100644 --- a/tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php +++ b/tests/ShareableMetrics/Metrics/ProjectNumberOfClassesTest.php @@ -18,7 +18,7 @@ public function it_returns_correct_metric_name() $metric = new ProjectNumberOfClasses($project); - $this->assertEquals('project_number_of_classes', $metric->name()); + $this->assertEquals('classes', $metric->name()); } /** @test */ From 0f8c6e77058c8d77baefa73135992da2600b97d6 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 27 Jun 2020 16:26:31 +0200 Subject: [PATCH 030/103] Update MetricsCollection and CollectMetrics MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ugh, naming 🙄 --- src/ShareableMetrics/CollectMetrics.php | 46 ++++++---------------- src/ShareableMetrics/MetricsCollection.php | 31 ++++++++++----- 2 files changed, 35 insertions(+), 42 deletions(-) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 1adffdb3..f7c696f4 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -2,10 +2,10 @@ namespace Wnx\LaravelStats\ShareableMetrics; +use Illuminate\Support\Collection; use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; -use Wnx\LaravelStats\ShareableMetrics\MetricsCollection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; @@ -16,7 +16,15 @@ class CollectMetrics { - public function get(Project $project) + public function collect(Project $project): MetricsCollection + { + return new MetricsCollection([ + 'project_metrics' => $this->getProjectMetrics($project), + 'component_metrics' => $this->getComponentMetrics($project) + ]); + } + + protected function getProjectMetrics(Project $project): Collection { $availableMetrics = collect([ InstalledPackages::class, @@ -32,23 +40,10 @@ public function get(Project $project) return new $statClass($project); }); - // Top Level Information about a project - $metrics = [ - 'project' => app(ProjectId::class)->get(), - 'metrics' => [], - ]; - - $projectMetrics = $availableMetrics->map->toArray()->collapse(); - $componentMetrics = $this->getComponentMetrics($project); - - $metrics['metrics'] = $projectMetrics->merge($componentMetrics)->sortKeys(); - - - return new MetricsCollection($metrics); + return $availableMetrics->map->toArray()->collapse(); } - - protected function getComponentMetrics(Project $project): array + protected function getComponentMetrics(Project $project): Collection { // Get the Names of "Core"-Components $coreClassifierNames = array_map(function ($classifier) { @@ -61,7 +56,6 @@ protected function getComponentMetrics(Project $project): array return new Component($componentName, $classifiedClasses); }); - $metrics = []; /** @var Component $component */ @@ -75,20 +69,6 @@ protected function getComponentMetrics(Project $project): array $metrics["{$slug}_lloc_per_method"] = $component->getLogicalLinesOfCodePerMethod(); } - - // TODO: After collection the metrics, collapse the browserkit, dusk and phpunit values into "tests" - // $tests = [ - // 'BrowserKit Tests', - // 'DuskTests', - // 'PHPUnit Tests' - // ]; - - // if (in_array($component->name, $tests)) { - // $slug = 'tests'; - // } else { - // $slug = Str::slug(strtolower($component->name), '_'); - // } - - return $metrics; + return collect($metrics); } } diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php index f44bbadb..5a1caf41 100644 --- a/src/ShareableMetrics/MetricsCollection.php +++ b/src/ShareableMetrics/MetricsCollection.php @@ -8,20 +8,33 @@ class MetricsCollection extends Collection { public function toAsciiTableFormat(): array { - $metrics = $this->items['metrics']; + $metrics = $this->items['project_metrics'] + ->map(function ($metric) { + if (is_array($metric)) { + return json_encode($metric, JSON_PRETTY_PRINT); + } - $metrics = $metrics->map(function ($metric) { - if (is_array($metric)) { - return json_encode($metric, JSON_PRETTY_PRINT); - } - - return $metric; - }); + return $metric; + }); return $metrics ->keys() ->zip($metrics) - ->push(['project', $this->items['project']]) ->toArray(); } + + public function toHttpPayload(string $projectName): array + { + $projectMetrics = $this->get('project_metrics'); + $componentMetrics = $this->get('component_metrics'); + + return [ + 'project' => $projectName, + 'metrics' => $projectMetrics + ->merge($componentMetrics) + ->sortKeys() + ->toArray() + ]; + } + } From bcec7668d526234c64a3099e61f94585fc93c3bd Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 27 Jun 2020 16:35:14 +0200 Subject: [PATCH 031/103] Update how ProjectName is determined --- src/ShareableMetrics/ProjectId.php | 26 -------------- src/ShareableMetrics/ProjectName.php | 53 ++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+), 26 deletions(-) delete mode 100644 src/ShareableMetrics/ProjectId.php create mode 100644 src/ShareableMetrics/ProjectName.php diff --git a/src/ShareableMetrics/ProjectId.php b/src/ShareableMetrics/ProjectId.php deleted file mode 100644 index e8eed14b..00000000 --- a/src/ShareableMetrics/ProjectId.php +++ /dev/null @@ -1,26 +0,0 @@ -toString(), function ($projectId) use ($pathToRcFile) { - File::put($pathToRcFile, $projectId); - }); - } -} diff --git a/src/ShareableMetrics/ProjectName.php b/src/ShareableMetrics/ProjectName.php new file mode 100644 index 00000000..6e0521f0 --- /dev/null +++ b/src/ShareableMetrics/ProjectName.php @@ -0,0 +1,53 @@ +hasStoredProjectName()) { + return File::get($this->pathToRcFile()); + } + + return null; + } + + public function determineProjectNameFromGit(): ?string + { + $process = Process::fromShellCommandline('/usr/local/bin/git config --get remote.origin.url'); + + $process->run(); + + if ($process->isSuccessful() === false) { + return null; + } + + $remoteUrl = parse_url(trim($process->getOutput())); + + return Str::of($remoteUrl['path']) + ->replaceFirst('/', '') + ->__toString(); + } + + protected function pathToRcFile(): string + { + return base_path(self::RC_FILE); + } + + public function hasStoredProjectName(): bool + { + return File::exists($this->pathToRcFile()); + } + + public function storeNameInRcFile(string $projectName): void + { + File::put($this->pathToRcFile(), $projectName); + } +} From a21f08a28ea4032ada620d41003867b17ceaf59e Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 27 Jun 2020 16:35:45 +0200 Subject: [PATCH 032/103] Install symfony/process --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 24d451e0..391d9c23 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,8 @@ "illuminate/console": "^7.0", "illuminate/support": "^7.0", "phploc/phploc": "~6.0", - "symfony/finder": "~5.0" + "symfony/finder": "~5.0", + "symfony/process": "~5.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.15", From d2628779a82d43cdadfc4736a7526c7ede67dd30 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 27 Jun 2020 16:57:28 +0200 Subject: [PATCH 033/103] Update Stats Command --- src/Console/StatsListCommand.php | 78 ++++++++++++++++----- src/ShareableMetrics/MetricsCollection.php | 1 + src/ShareableMetrics/SendToLaravelShift.php | 24 ++----- 3 files changed, 66 insertions(+), 37 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 8cc647b3..21528153 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -11,6 +11,7 @@ use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\RejectionStrategies\RejectVendorClasses; use Wnx\LaravelStats\ShareableMetrics\CollectMetrics; +use Wnx\LaravelStats\ShareableMetrics\ProjectName; use Wnx\LaravelStats\ShareableMetrics\SendToLaravelShift; class StatsListCommand extends Command @@ -58,6 +59,24 @@ public function handle() $project = new Project($reflectionClasses); + $this->renderOutput($project); + + if ($this->option('share') === true) { + $this->shareDataWithShift($project); + } + } + + private function getArrayOfComponentsToDisplay(): array + { + if (is_null($this->option('components'))) { + return []; + } + + return explode(',', $this->option('components')); + } + + private function renderOutput(Project $project) + { if ($this->option('json') === true) { $json = (new JsonOutput())->render( $project, @@ -73,33 +92,54 @@ public function handle() $this->getArrayOfComponentsToDisplay() ); } + } - if ($this->option('share') === true) { + private function shareDataWithShift(Project $project): void + { + $metrics = app(CollectMetrics::class)->collect($project); + + $this->info("\n\n"); + $this->info("The following metrics will be shared with stats.laravelshift.com."); + $this->table( + ['Name', 'Value'], + $metrics->toAsciiTableFormat() + ); - // TODO: Collect the Metrics - // TODO: Get Project Name from local Git Repo - // TODO: Show Collected Metrics to User - // TODO: Ask user to confirm the project name + if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { - $metrics = app(CollectMetrics::class)->get($project); + if (app(ProjectName::class)->hasStoredProjectName() === false) { - $this->table( - ['Name', 'Value'], - $metrics->toAsciiTableFormat() + $generatedProjectName = app(ProjectName::class)->determineProjectNameFromGit(); + + $projectName = $this->ask("We've determined the following name for your project. Do you want to rename it?", $generatedProjectName); + + $this->info(); + + app(ProjectName::class)->storeNameInRcFile($projectName); + + } else { + $projectName = app(ProjectName::class)->get(); + } + + if ($projectName === null) { + $this->error("Please provide a project name."); + return; + } + + $response = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); + + dd( + $response->status(), + $response->body() ); - if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { - // app(SendToLaravelShift::class)->send($metrics); + if ($response->failed()) { + $this->error("An error occured while transmitting data to laravelshift.com. Please try again."); } - } - } - private function getArrayOfComponentsToDisplay(): array - { - if (is_null($this->option('components'))) { - return []; + if ($response->successful()) { + $this->info("Thanks for sharing your project data with the community!"); + } } - - return explode(',', $this->option('components')); } } diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php index 5a1caf41..ceab62d5 100644 --- a/src/ShareableMetrics/MetricsCollection.php +++ b/src/ShareableMetrics/MetricsCollection.php @@ -18,6 +18,7 @@ public function toAsciiTableFormat(): array }); return $metrics + ->forget('packages') ->keys() ->zip($metrics) ->toArray(); diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index a758a0df..1056d1ca 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -2,31 +2,19 @@ namespace Wnx\LaravelStats\ShareableMetrics; +use Illuminate\Http\Client\Response; use Illuminate\Support\Facades\Http; class SendToLaravelShift { - public function send(array $payload): void + public function send(array $payload): Response { - $httpPayload = [ - 'project' => $payload['project'], - 'metrics' => $payload['metrics']->toArray() - ]; + info('Send laravel-stats data to Laravel Shift', $payload); - info(json_encode($httpPayload)); + dd($payload); - // TODO: Replace with URL to Stats API - $response = Http::withHeaders([ + return Http::withHeaders([ 'Accept' => 'application/json' - ])->post('https://laravelshift.com/api/stat', $httpPayload); - - dd( - $response->status(), - $response->body() - ); - - if ($response->failed()) { - dd($response->json()); - } + ])->post('https://laravelshift.com/api/stat', $payload); } } From bd77303221c3a754a397504539734588f80d93c5 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 27 Jun 2020 17:00:37 +0200 Subject: [PATCH 034/103] WIP --- src/ShareableMetrics/MetricsCollection.php | 7 +++---- src/ShareableMetrics/ProjectName.php | 1 - 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php index ceab62d5..f7bc22b1 100644 --- a/src/ShareableMetrics/MetricsCollection.php +++ b/src/ShareableMetrics/MetricsCollection.php @@ -8,7 +8,7 @@ class MetricsCollection extends Collection { public function toAsciiTableFormat(): array { - $metrics = $this->items['project_metrics'] + $projectMetrics = $this->items['project_metrics'] ->map(function ($metric) { if (is_array($metric)) { return json_encode($metric, JSON_PRETTY_PRINT); @@ -17,10 +17,10 @@ public function toAsciiTableFormat(): array return $metric; }); - return $metrics + return $projectMetrics ->forget('packages') ->keys() - ->zip($metrics) + ->zip($projectMetrics) ->toArray(); } @@ -37,5 +37,4 @@ public function toHttpPayload(string $projectName): array ->toArray() ]; } - } diff --git a/src/ShareableMetrics/ProjectName.php b/src/ShareableMetrics/ProjectName.php index 6e0521f0..24a19f48 100644 --- a/src/ShareableMetrics/ProjectName.php +++ b/src/ShareableMetrics/ProjectName.php @@ -22,7 +22,6 @@ public function get(): ?string public function determineProjectNameFromGit(): ?string { $process = Process::fromShellCommandline('/usr/local/bin/git config --get remote.origin.url'); - $process->run(); if ($process->isSuccessful() === false) { From a98d050490ca436e3547aaad118a31808cd7aba8 Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Sat, 27 Jun 2020 15:01:06 +0000 Subject: [PATCH 035/103] Apply php-cs-fixer changes --- src/Console/StatsListCommand.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 21528153..fdcba508 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -106,9 +106,7 @@ private function shareDataWithShift(Project $project): void ); if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { - if (app(ProjectName::class)->hasStoredProjectName() === false) { - $generatedProjectName = app(ProjectName::class)->determineProjectNameFromGit(); $projectName = $this->ask("We've determined the following name for your project. Do you want to rename it?", $generatedProjectName); @@ -116,7 +114,6 @@ private function shareDataWithShift(Project $project): void $this->info(); app(ProjectName::class)->storeNameInRcFile($projectName); - } else { $projectName = app(ProjectName::class)->get(); } From 4a2907647753efd0214425124cbd29495ef60915 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 27 Jun 2020 17:05:19 +0200 Subject: [PATCH 036/103] Display which project name was used --- src/Console/StatsListCommand.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index fdcba508..73f42563 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -111,8 +111,6 @@ private function shareDataWithShift(Project $project): void $projectName = $this->ask("We've determined the following name for your project. Do you want to rename it?", $generatedProjectName); - $this->info(); - app(ProjectName::class)->storeNameInRcFile($projectName); } else { $projectName = app(ProjectName::class)->get(); @@ -123,6 +121,8 @@ private function shareDataWithShift(Project $project): void return; } + $this->info("The project name '{$projectName}' will be used."); + $response = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); dd( From d414bc07eabb072588edfc142a8a4d03676d42bc Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 29 Jun 2020 19:27:48 +0200 Subject: [PATCH 037/103] Add ext-json to composer --- composer.json | 1 + 1 file changed, 1 insertion(+) diff --git a/composer.json b/composer.json index 391d9c23..c35bee26 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,7 @@ ], "require": { "php": ">=7.3.0", + "ext-json": "*", "illuminate/console": "^7.0", "illuminate/support": "^7.0", "phploc/phploc": "~6.0", From e4c437642180e611b1f85f2251c62385141f80f3 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 29 Jun 2020 20:33:15 +0200 Subject: [PATCH 038/103] Add ModelsUseGuardedOrFillable --- src/ShareableMetrics/CollectMetrics.php | 2 + .../Metrics/ModelsUseGuardedOrFillable.php | 44 +++++++++++++++++ .../ModelsUseGuardedOrFillableTest.php | 49 +++++++++++++++++++ tests/Stubs/Models/Post.php | 2 + tests/Stubs/Models/User.php | 2 + 5 files changed, 99 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/ModelsUseGuardedOrFillable.php create mode 100644 tests/ShareableMetrics/Metrics/ModelsUseGuardedOrFillableTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index f7c696f4..31d6e4e4 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -7,6 +7,7 @@ use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; @@ -33,6 +34,7 @@ protected function getProjectMetrics(Project $project): Collection ProjectLinesOfCode::class, ProjectLogicalLinesOfCode::class, ProjectNumberOfClasses::class, + ModelsUseGuardedOrFillable::class, // CodeLogicalLinesOfCode // TestLogicalLinesOfCode // CodeToTestRatio diff --git a/src/ShareableMetrics/Metrics/ModelsUseGuardedOrFillable.php b/src/ShareableMetrics/Metrics/ModelsUseGuardedOrFillable.php new file mode 100644 index 00000000..d60a7a32 --- /dev/null +++ b/src/ShareableMetrics/Metrics/ModelsUseGuardedOrFillable.php @@ -0,0 +1,44 @@ +project + ->classifiedClasses() + ->filter(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->classifier->name() === 'Models'; + }) + ->map(function (ClassifiedClass $classifiedClass) { + + // Collect all properties of the given class, + // filter to only keep "guarded" and "fillable" + // and only keep those which have been set by the developer. + return collect($classifiedClass->reflectionClass->getProperties()) + ->filter(function (ReflectionProperty $property) { + return in_array($property->getName(), ['guarded', 'fillable']); + }) + ->filter(function (ReflectionProperty $property) use ($classifiedClass) { + return $property->class === $classifiedClass->reflectionClass->name; + }) + ->toArray(); + }) + ->filter() + ->flatten(1) + ->countBy(function (ReflectionProperty $property) { + return $property->getName(); + }) + ->toArray(); + } +} diff --git a/tests/ShareableMetrics/Metrics/ModelsUseGuardedOrFillableTest.php b/tests/ShareableMetrics/Metrics/ModelsUseGuardedOrFillableTest.php new file mode 100644 index 00000000..e680f427 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ModelsUseGuardedOrFillableTest.php @@ -0,0 +1,49 @@ +createProjectFromClasses([]); + + $metric = new ModelsUseGuardedOrFillable($project); + + $this->assertEquals('models_guarded_fillable', $metric->name()); + } + + /** @test */ + public function it_returns_an_empty_array_if_project_does_not_contain_models() + { + $project = $this->createProjectFromClasses([]); + + $metric = new ModelsUseGuardedOrFillable($project); + + $this->assertEquals([], $metric->value()); + } + + /** @test */ + public function it_returns_the_number_of_guarded_and_unguarded_models_in_the_return_array() + { + $project = $this->createProjectFromClasses([ + User::class, + Post::class, + Group::class + ]); + + $metric = new ModelsUseGuardedOrFillable($project); + + $this->assertEquals([ + 'guarded' => 1, + 'fillable' => 1, + ], $metric->value()); + } +} diff --git a/tests/Stubs/Models/Post.php b/tests/Stubs/Models/Post.php index 61e84583..65f566fc 100644 --- a/tests/Stubs/Models/Post.php +++ b/tests/Stubs/Models/Post.php @@ -7,6 +7,8 @@ class Post extends Model { + protected $guarded = []; + public function user(): BelongsTo { return $this->belongsTo(User::class); diff --git a/tests/Stubs/Models/User.php b/tests/Stubs/Models/User.php index b408082c..2279fb6e 100644 --- a/tests/Stubs/Models/User.php +++ b/tests/Stubs/Models/User.php @@ -8,6 +8,8 @@ class User extends Model { + protected $fillable = []; + public function projects(): HasMany { return $this->hasMany(Project::class); From e11cb16513f685e6848a5b3b7766c3c4c4394480 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 29 Jun 2020 20:33:19 +0200 Subject: [PATCH 039/103] Update Tests --- tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php | 2 +- .../ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php index e4dcc3ce..dde54607 100644 --- a/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php +++ b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php @@ -33,6 +33,6 @@ public function it_returns_the_correct_total_number_lines_of_code_for_the_projec $metric = new ProjectLinesOfCode($project); - $this->assertEquals(118, $metric->value()); + $this->assertEquals(120, $metric->value()); } } diff --git a/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php b/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php index 0bba2012..72d5ed9c 100644 --- a/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php +++ b/tests/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodeTest.php @@ -33,6 +33,6 @@ public function it_returns_the_correct_total_number_logical_lines_of_code_for_th $metric = new ProjectLogicalLinesOfCode($project); - $this->assertEquals(11.0, $metric->value()); + $this->assertEquals(12.0, $metric->value()); } } From 04f557ba3ce1f1e67b8ae883b7fe68708beb0825 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 29 Jun 2020 21:05:34 +0200 Subject: [PATCH 040/103] Add ControllerFormRequestInjection --- .../ControllerFormRequestInjection.php | 49 +++++++++++++++++ .../ControllerFormRequestInjectionTest.php | 52 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php create mode 100644 tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php diff --git a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php new file mode 100644 index 00000000..88efcee2 --- /dev/null +++ b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php @@ -0,0 +1,49 @@ +project + ->classifiedClasses() + ->filter(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->classifier->name() === 'Controllers'; + }) + ->map(function (ClassifiedClass $classifiedClass) { + + $methods = collect($classifiedClass->reflectionClass->getDefinedMethods()); + + return $methods->filter(function (ReflectionMethod $method) { + return count($method->getParameters()) > 0; + }) + ->filter(function (ReflectionMethod $method) { + return collect($method->getParameters()) + ->filter(function (ReflectionParameter $param) { + return $param->hasType(); + }) + ->filter(function (ReflectionParameter $param) { + + $reflectionClass = new ReflectionClass($param->getType()->getName()); + + return $reflectionClass->isSubclassOf(FormRequest::class); + }); + }) + ->count() > 0; + })->count() > 0; + } +} diff --git a/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php b/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php new file mode 100644 index 00000000..a4930acf --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php @@ -0,0 +1,52 @@ +createProjectFromClasses([]); + + $metric = new ControllerFormRequestInjection($project); + + $this->assertEquals('controllers_form_request_injection', $metric->name()); + } + + /** @test */ + public function it_returns_true_if_controllers_do_use_form_request_injection() + { + Route::get('users', [UsersController::class, 'index']); + + $project = $this->createProjectFromClasses([ + UsersController::class + ]); + + $metric = new ControllerFormRequestInjection($project); + + $this->assertTrue($metric->value()); + } + + /** @test */ + public function it_returns_false_if_controllers_do_not_use_form_request_injection() + { + $this->markTestIncomplete("This test shouldn't fail."); + + Route::get('projects', [ProjectsController::class, 'index']); + + $project = $this->createProjectFromClasses([ + ProjectsController::class + ]); + + $metric = new ControllerFormRequestInjection($project); + + $this->assertFalse($metric->value()); + } +} From 24f26aeb741ad0f85dae8593bc94b94ac8376c56 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 29 Jun 2020 21:05:53 +0200 Subject: [PATCH 041/103] Update Tests --- tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php | 2 +- tests/Stubs/Controllers/UsersController.php | 6 ++++-- tests/ValueObjects/ClassifiedClassTest.php | 2 +- tests/ValueObjects/ComponentTest.php | 2 +- 4 files changed, 7 insertions(+), 5 deletions(-) diff --git a/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php index dde54607..ca3aa075 100644 --- a/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php +++ b/tests/ShareableMetrics/Metrics/ProjectLinesOfCodeTest.php @@ -33,6 +33,6 @@ public function it_returns_the_correct_total_number_lines_of_code_for_the_projec $metric = new ProjectLinesOfCode($project); - $this->assertEquals(120, $metric->value()); + $this->assertEquals(122, $metric->value()); } } diff --git a/tests/Stubs/Controllers/UsersController.php b/tests/Stubs/Controllers/UsersController.php index 4cd82ab0..88b56c6b 100644 --- a/tests/Stubs/Controllers/UsersController.php +++ b/tests/Stubs/Controllers/UsersController.php @@ -2,6 +2,8 @@ namespace Wnx\LaravelStats\Tests\Stubs\Controllers; +use Wnx\LaravelStats\Tests\Stubs\Requests\UserRequest; + class UsersController extends Controller { public function index() @@ -14,7 +16,7 @@ public function create() return []; } - public function store() + public function store(UserRequest $request) { return []; } @@ -29,7 +31,7 @@ public function edit() return []; } - public function update() + public function update(UserRequest $request) { return []; } diff --git a/tests/ValueObjects/ClassifiedClassTest.php b/tests/ValueObjects/ClassifiedClassTest.php index 4101921a..cde84c44 100644 --- a/tests/ValueObjects/ClassifiedClassTest.php +++ b/tests/ValueObjects/ClassifiedClassTest.php @@ -31,7 +31,7 @@ public function it_returns_number_of_methods_for_a_classified_class() public function it_returns_number_of_lines_of_code_for_a_classified_class() { $this->assertEquals( - 41, + 43, $this->getClassifiedClass()->getLines() ); } diff --git a/tests/ValueObjects/ComponentTest.php b/tests/ValueObjects/ComponentTest.php index aa764150..0d3b2005 100644 --- a/tests/ValueObjects/ComponentTest.php +++ b/tests/ValueObjects/ComponentTest.php @@ -60,7 +60,7 @@ public function it_returns_total_number_of_lines_of_code_for_all_classes_within_ { $component = $this->getTestComponent(); - $this->assertEquals(103, $component->getLinesOfCode()); + $this->assertEquals(105, $component->getLinesOfCode()); } /** @test */ From ab004217bdae9c16e15198946379c219aff96ea5 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 29 Jun 2020 21:07:42 +0200 Subject: [PATCH 042/103] Cast booleans to strings in ASCII Table --- src/ShareableMetrics/MetricsCollection.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php index f7bc22b1..809f7bd7 100644 --- a/src/ShareableMetrics/MetricsCollection.php +++ b/src/ShareableMetrics/MetricsCollection.php @@ -14,6 +14,14 @@ public function toAsciiTableFormat(): array return json_encode($metric, JSON_PRETTY_PRINT); } + if ($metric === true) { + return 'true'; + } + + if ($metric === false) { + return 'false'; + } + return $metric; }); From 15d7f14d5785fe1fb39c903de328eb65af6cf7c1 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 29 Jun 2020 21:07:54 +0200 Subject: [PATCH 043/103] Use ControllerFormRequestInjection Metric --- src/ShareableMetrics/CollectMetrics.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 31d6e4e4..bbf88a8e 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -6,6 +6,7 @@ use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllerFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; @@ -35,6 +36,7 @@ protected function getProjectMetrics(Project $project): Collection ProjectLogicalLinesOfCode::class, ProjectNumberOfClasses::class, ModelsUseGuardedOrFillable::class, + ControllerFormRequestInjection::class, // CodeLogicalLinesOfCode // TestLogicalLinesOfCode // CodeToTestRatio From 0d6ee332f3d16eb27affecf28f38f74b2fb41c4c Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Mon, 29 Jun 2020 19:08:23 +0000 Subject: [PATCH 044/103] Apply php-cs-fixer changes --- .../Metrics/ControllerFormRequestInjection.php | 7 ++----- .../Metrics/ControllerFormRequestInjectionTest.php | 2 +- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php index 88efcee2..384cda82 100644 --- a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php +++ b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php @@ -5,7 +5,6 @@ use Illuminate\Foundation\Http\FormRequest; use ReflectionMethod; use ReflectionParameter; -use ReflectionProperty; use Wnx\LaravelStats\Contracts\CollectableMetric; use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; @@ -25,19 +24,17 @@ public function value() return $classifiedClass->classifier->name() === 'Controllers'; }) ->map(function (ClassifiedClass $classifiedClass) { - $methods = collect($classifiedClass->reflectionClass->getDefinedMethods()); return $methods->filter(function (ReflectionMethod $method) { - return count($method->getParameters()) > 0; - }) + return count($method->getParameters()) > 0; + }) ->filter(function (ReflectionMethod $method) { return collect($method->getParameters()) ->filter(function (ReflectionParameter $param) { return $param->hasType(); }) ->filter(function (ReflectionParameter $param) { - $reflectionClass = new ReflectionClass($param->getType()->getName()); return $reflectionClass->isSubclassOf(FormRequest::class); diff --git a/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php b/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php index a4930acf..e5104aff 100644 --- a/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php +++ b/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php @@ -1,4 +1,4 @@ - Date: Mon, 29 Jun 2020 19:08:23 +0000 Subject: [PATCH 045/103] Simplify ControllerFormRequestInjection --- .../ControllerFormRequestInjection.php | 42 +++++++++---------- .../ControllerFormRequestInjectionTest.php | 2 - 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php index 384cda82..ee12bdb1 100644 --- a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php +++ b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php @@ -2,9 +2,9 @@ namespace Wnx\LaravelStats\ShareableMetrics\Metrics; -use Illuminate\Foundation\Http\FormRequest; use ReflectionMethod; use ReflectionParameter; +use Wnx\LaravelStats\Classifiers\RequestClassifier; use Wnx\LaravelStats\Contracts\CollectableMetric; use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; @@ -19,28 +19,28 @@ public function name(): string public function value() { return $this->project - ->classifiedClasses() - ->filter(function (ClassifiedClass $classifiedClass) { - return $classifiedClass->classifier->name() === 'Controllers'; - }) - ->map(function (ClassifiedClass $classifiedClass) { - $methods = collect($classifiedClass->reflectionClass->getDefinedMethods()); - - return $methods->filter(function (ReflectionMethod $method) { + ->classifiedClasses() + ->filter(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->classifier->name() === 'Controllers'; + }) + ->flatMap(function (ClassifiedClass $classifiedClass) { + return collect($classifiedClass->reflectionClass->getDefinedMethods()); + }) + ->filter(function (ReflectionMethod $method) { return count($method->getParameters()) > 0; }) - ->filter(function (ReflectionMethod $method) { - return collect($method->getParameters()) - ->filter(function (ReflectionParameter $param) { - return $param->hasType(); - }) - ->filter(function (ReflectionParameter $param) { - $reflectionClass = new ReflectionClass($param->getType()->getName()); + ->flatMap(function (ReflectionMethod $method) { + return collect($method->getParameters()); + }) + ->filter(function (ReflectionParameter $param) { + return $param->hasType(); + }) + ->filter(function (ReflectionParameter $param) { + + $reflectionClass = new ReflectionClass($param->getType()->getName()); - return $reflectionClass->isSubclassOf(FormRequest::class); - }); - }) - ->count() > 0; - })->count() > 0; + return app(RequestClassifier::class)->satisfies($reflectionClass); + }) + ->count() > 0; } } diff --git a/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php b/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php index e5104aff..cd52a931 100644 --- a/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php +++ b/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php @@ -37,8 +37,6 @@ public function it_returns_true_if_controllers_do_use_form_request_injection() /** @test */ public function it_returns_false_if_controllers_do_not_use_form_request_injection() { - $this->markTestIncomplete("This test shouldn't fail."); - Route::get('projects', [ProjectsController::class, 'index']); $project = $this->createProjectFromClasses([ From 3429c78b1e92e66ace516d6fa851c340ea03bac3 Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Tue, 30 Jun 2020 19:10:10 +0000 Subject: [PATCH 046/103] Apply php-cs-fixer changes --- src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php index ee12bdb1..25d37604 100644 --- a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php +++ b/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php @@ -36,7 +36,6 @@ public function value() return $param->hasType(); }) ->filter(function (ReflectionParameter $param) { - $reflectionClass = new ReflectionClass($param->getType()->getName()); return app(RequestClassifier::class)->satisfies($reflectionClass); From 70457d43e40139282af5039d148e16bd13fc8806 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 7 Jul 2020 19:55:38 +0200 Subject: [PATCH 047/103] Add CodeTestRatio Metric --- src/ShareableMetrics/CollectMetrics.php | 5 +-- .../Metrics/CodeTestRatio.php | 20 ++++++++++ .../Metrics/CodeTestRatioTest.php | 38 +++++++++++++++++++ 3 files changed, 60 insertions(+), 3 deletions(-) create mode 100644 src/ShareableMetrics/Metrics/CodeTestRatio.php create mode 100644 tests/ShareableMetrics/Metrics/CodeTestRatioTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index bbf88a8e..30413951 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -6,6 +6,7 @@ use Illuminate\Support\Str; use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; +use Wnx\LaravelStats\ShareableMetrics\Metrics\CodeTestRatio; use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllerFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; @@ -37,9 +38,7 @@ protected function getProjectMetrics(Project $project): Collection ProjectNumberOfClasses::class, ModelsUseGuardedOrFillable::class, ControllerFormRequestInjection::class, - // CodeLogicalLinesOfCode - // TestLogicalLinesOfCode - // CodeToTestRatio + CodeTestRatio::class, ])->map(function ($statClass) use ($project) { return new $statClass($project); }); diff --git a/src/ShareableMetrics/Metrics/CodeTestRatio.php b/src/ShareableMetrics/Metrics/CodeTestRatio.php new file mode 100644 index 00000000..78972b2d --- /dev/null +++ b/src/ShareableMetrics/Metrics/CodeTestRatio.php @@ -0,0 +1,20 @@ +project->statistic()->getApplicationCodeToTestCodeRatio(); + } +} diff --git a/tests/ShareableMetrics/Metrics/CodeTestRatioTest.php b/tests/ShareableMetrics/Metrics/CodeTestRatioTest.php new file mode 100644 index 00000000..762310a6 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/CodeTestRatioTest.php @@ -0,0 +1,38 @@ +createProjectFromClasses([]); + + $metric = new CodeTestRatio($project); + + $this->assertEquals('code_test_ratio', $metric->name()); + } + + /** @test */ + public function it_returns_ratio_of_app_and_test_code() + { + $project = $this->createProjectFromClasses([ + User::class, + DemoDuskTest::class, + DemoUnitTest::class, + DemoBrowserKit::class, + ]); + + $metric = new CodeTestRatio($project); + + $this->assertEquals(0.8, $metric->value()); + } +} From 7ae6677195a69c78a80d7db6e688a1b67cc717dd Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 7 Jul 2020 20:22:58 +0200 Subject: [PATCH 048/103] Add ModelsFolder Metric --- src/ShareableMetrics/CollectMetrics.php | 2 + src/ShareableMetrics/Metrics/ModelsFolder.php | 41 +++++++++++++ .../Metrics/ModelsFolderTest.php | 59 +++++++++++++++++++ 3 files changed, 102 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/ModelsFolder.php create mode 100644 tests/ShareableMetrics/Metrics/ModelsFolderTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 30413951..58f6448f 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -9,6 +9,7 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\CodeTestRatio; use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllerFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; @@ -39,6 +40,7 @@ protected function getProjectMetrics(Project $project): Collection ModelsUseGuardedOrFillable::class, ControllerFormRequestInjection::class, CodeTestRatio::class, + ModelsFolder::class, ])->map(function ($statClass) use ($project) { return new $statClass($project); }); diff --git a/src/ShareableMetrics/Metrics/ModelsFolder.php b/src/ShareableMetrics/Metrics/ModelsFolder.php new file mode 100644 index 00000000..a304bfa9 --- /dev/null +++ b/src/ShareableMetrics/Metrics/ModelsFolder.php @@ -0,0 +1,41 @@ +project + ->classifiedClasses() + ->filter(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->classifier->name() === 'Models'; + }); + + if ($models->count() === 0) { + return null; + } + + return $models + ->map(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->reflectionClass->getNamespaceName(); + }) + ->filter(function (string $namespace) { + // If a Models namespace contains a back-slash, we assume that the Model + // is not located in the default location under /app, but somewhere else + return Str::of($namespace)->contains("\\"); + }) + ->count() > 0; + } +} diff --git a/tests/ShareableMetrics/Metrics/ModelsFolderTest.php b/tests/ShareableMetrics/Metrics/ModelsFolderTest.php new file mode 100644 index 00000000..da76b2ec --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ModelsFolderTest.php @@ -0,0 +1,59 @@ +createProjectFromClasses([]); + + $metric = new ModelsFolder($project); + + $this->assertEquals('models_folder', $metric->name()); + } + + /** @test */ + public function it_returns_null_if_no_models_are_found_in_the_project() + { + $project = $this->createProjectFromClasses([ + // + ]); + + $metric = new ModelsFolder($project); + + $this->assertNull($metric->value()); + } + + /** @test */ + public function it_returns_false_if_models_are_stored_in_default_namespace() + { + $this->markTestIncomplete("Need to add Model under correct namespace for testing"); + + $project = $this->createProjectFromClasses([ + // Model located under App\ + ]); + + $metric = new ModelsFolder($project); + + $this->assertFalse($metric->value()); + } + + /** @test */ + public function it_returns_true_if_models_are_stored_in_non_default_namespace() + { + $project = $this->createProjectFromClasses([ + User::class, + ]); + + $metric = new ModelsFolder($project); + + $this->assertTrue($metric->value()); + } +} From 9de7f25a794439d4de669c9c0e576fa6ebc7910a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 7 Jul 2020 20:48:56 +0200 Subject: [PATCH 049/103] Rename ControllersFormRequestInjection --- src/ShareableMetrics/CollectMetrics.php | 4 ++-- ...jection.php => ControllersFormRequestInjection.php} | 2 +- ...est.php => ControllersFormRequestInjectionTest.php} | 10 +++++----- 3 files changed, 8 insertions(+), 8 deletions(-) rename src/ShareableMetrics/Metrics/{ControllerFormRequestInjection.php => ControllersFormRequestInjection.php} (95%) rename tests/ShareableMetrics/Metrics/{ControllerFormRequestInjectionTest.php => ControllersFormRequestInjectionTest.php} (78%) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 58f6448f..a8c3ee57 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -7,7 +7,7 @@ use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; use Wnx\LaravelStats\ShareableMetrics\Metrics\CodeTestRatio; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllerFormRequestInjection; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllersFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; @@ -38,7 +38,7 @@ protected function getProjectMetrics(Project $project): Collection ProjectLogicalLinesOfCode::class, ProjectNumberOfClasses::class, ModelsUseGuardedOrFillable::class, - ControllerFormRequestInjection::class, + ControllersFormRequestInjection::class, CodeTestRatio::class, ModelsFolder::class, ])->map(function ($statClass) use ($project) { diff --git a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php b/src/ShareableMetrics/Metrics/ControllersFormRequestInjection.php similarity index 95% rename from src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php rename to src/ShareableMetrics/Metrics/ControllersFormRequestInjection.php index 25d37604..20947170 100644 --- a/src/ShareableMetrics/Metrics/ControllerFormRequestInjection.php +++ b/src/ShareableMetrics/Metrics/ControllersFormRequestInjection.php @@ -9,7 +9,7 @@ use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; -class ControllerFormRequestInjection extends Metric implements CollectableMetric +class ControllersFormRequestInjection extends Metric implements CollectableMetric { public function name(): string { diff --git a/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php b/tests/ShareableMetrics/Metrics/ControllersFormRequestInjectionTest.php similarity index 78% rename from tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php rename to tests/ShareableMetrics/Metrics/ControllersFormRequestInjectionTest.php index cd52a931..29c1c286 100644 --- a/tests/ShareableMetrics/Metrics/ControllerFormRequestInjectionTest.php +++ b/tests/ShareableMetrics/Metrics/ControllersFormRequestInjectionTest.php @@ -3,19 +3,19 @@ namespace Wnx\LaravelStats\Tests\ShareableMetrics\Metrics; use Illuminate\Support\Facades\Route; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllerFormRequestInjection; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllersFormRequestInjection; use Wnx\LaravelStats\Tests\Stubs\Controllers\ProjectsController; use Wnx\LaravelStats\Tests\Stubs\Controllers\UsersController; use Wnx\LaravelStats\Tests\TestCase; -class ControllerFormRequestInjectionTest extends TestCase +class ControllersFormRequestInjectionTest extends TestCase { /** @test */ public function it_returns_correct_metric_name() { $project = $this->createProjectFromClasses([]); - $metric = new ControllerFormRequestInjection($project); + $metric = new ControllersFormRequestInjection($project); $this->assertEquals('controllers_form_request_injection', $metric->name()); } @@ -29,7 +29,7 @@ public function it_returns_true_if_controllers_do_use_form_request_injection() UsersController::class ]); - $metric = new ControllerFormRequestInjection($project); + $metric = new ControllersFormRequestInjection($project); $this->assertTrue($metric->value()); } @@ -43,7 +43,7 @@ public function it_returns_false_if_controllers_do_not_use_form_request_injectio ProjectsController::class ]); - $metric = new ControllerFormRequestInjection($project); + $metric = new ControllersFormRequestInjection($project); $this->assertFalse($metric->value()); } From 7a93a5ea5d5ad5deb7db7bcc67eb15cc3b9a8016 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 7 Jul 2020 20:54:47 +0200 Subject: [PATCH 050/103] Add ModelsExtendOtherModel --- src/ShareableMetrics/CollectMetrics.php | 2 + .../Metrics/ModelsExtendOtherModel.php | 39 ++++++++++++ .../Metrics/ModelsExtendOtherModelTest.php | 62 +++++++++++++++++++ tests/Stubs/Models/BaseModel.php | 10 +++ tests/Stubs/Models/Group.php | 3 +- 5 files changed, 114 insertions(+), 2 deletions(-) create mode 100644 src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php create mode 100644 tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php create mode 100644 tests/Stubs/Models/BaseModel.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index a8c3ee57..6f7ebf74 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -9,6 +9,7 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\CodeTestRatio; use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllersFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsExtendOtherModel; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; @@ -41,6 +42,7 @@ protected function getProjectMetrics(Project $project): Collection ControllersFormRequestInjection::class, CodeTestRatio::class, ModelsFolder::class, + ModelsExtendOtherModel::class, ])->map(function ($statClass) use ($project) { return new $statClass($project); }); diff --git a/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php b/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php new file mode 100644 index 00000000..d672fc49 --- /dev/null +++ b/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php @@ -0,0 +1,39 @@ +project + ->classifiedClasses() + ->filter(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->classifier->name() === 'Models'; + }); + + if ($models->count() === 0) { + return null; + } + + return $models + ->reject(function (ClassifiedClass $classifiedClass) { + + $parentClassName = $classifiedClass->reflectionClass->getParentClass()->getName(); + + // If a Model extends an Illuminate-class, remove it from the collection + // as we see it as a "normal" Model + return Str::of($parentClassName)->startsWith('Illuminate'); + }) + ->count() > 0; + } +} diff --git a/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php b/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php new file mode 100644 index 00000000..6a1aaf70 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php @@ -0,0 +1,62 @@ +createProjectFromClasses([]); + + $metric = new ModelsExtendOtherModel($project); + + $this->assertEquals('models_extend_model', $metric->name()); + } + + /** @test */ + public function it_returns_null_if_no_models_are_found_in_the_project() + { + $project = $this->createProjectFromClasses([ + // + ]); + + $metric = new ModelsExtendOtherModel($project); + + $this->assertNull($metric->value()); + } + + + /** @test */ + public function it_returns_true_if_models_extends_another_model_in_the_project() + { + $project = $this->createProjectFromClasses([ + Group::class + ]); + + $metric = new ModelsExtendOtherModel($project); + + $this->assertTrue($metric->value()); + } + + /** @test */ + public function it_returns_false_if_models_does_not_extend_another_model_in_the_project() + { + $project = $this->createProjectFromClasses([ + User::class + ]); + + $metric = new ModelsExtendOtherModel($project); + + $this->assertFalse($metric->value()); + } +} diff --git a/tests/Stubs/Models/BaseModel.php b/tests/Stubs/Models/BaseModel.php new file mode 100644 index 00000000..73914737 --- /dev/null +++ b/tests/Stubs/Models/BaseModel.php @@ -0,0 +1,10 @@ + Date: Tue, 7 Jul 2020 18:55:26 +0000 Subject: [PATCH 051/103] Apply php-cs-fixer changes --- src/ShareableMetrics/Metrics/CodeTestRatio.php | 2 -- src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php | 1 - src/ShareableMetrics/Metrics/ModelsFolder.php | 2 -- tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php | 4 ---- 4 files changed, 9 deletions(-) diff --git a/src/ShareableMetrics/Metrics/CodeTestRatio.php b/src/ShareableMetrics/Metrics/CodeTestRatio.php index 78972b2d..8720908c 100644 --- a/src/ShareableMetrics/Metrics/CodeTestRatio.php +++ b/src/ShareableMetrics/Metrics/CodeTestRatio.php @@ -2,8 +2,6 @@ namespace Wnx\LaravelStats\ShareableMetrics\Metrics; -use Illuminate\Support\Arr; -use Illuminate\Support\Facades\File; use Wnx\LaravelStats\Contracts\CollectableMetric; class CodeTestRatio extends Metric implements CollectableMetric diff --git a/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php b/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php index d672fc49..04349fb9 100644 --- a/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php +++ b/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php @@ -27,7 +27,6 @@ public function value() return $models ->reject(function (ClassifiedClass $classifiedClass) { - $parentClassName = $classifiedClass->reflectionClass->getParentClass()->getName(); // If a Model extends an Illuminate-class, remove it from the collection diff --git a/src/ShareableMetrics/Metrics/ModelsFolder.php b/src/ShareableMetrics/Metrics/ModelsFolder.php index a304bfa9..487af95f 100644 --- a/src/ShareableMetrics/Metrics/ModelsFolder.php +++ b/src/ShareableMetrics/Metrics/ModelsFolder.php @@ -2,8 +2,6 @@ namespace Wnx\LaravelStats\ShareableMetrics\Metrics; -use Illuminate\Support\Arr; -use Illuminate\Support\Facades\File; use Illuminate\Support\Str; use Wnx\LaravelStats\Contracts\CollectableMetric; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; diff --git a/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php b/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php index 6a1aaf70..e3313b42 100644 --- a/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php +++ b/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php @@ -2,11 +2,7 @@ namespace Wnx\LaravelStats\Tests\ShareableMetrics\Metrics; -use Illuminate\Support\Facades\Route; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsExtendOtherModel; -use Wnx\LaravelStats\Tests\Stubs\Controllers\PostsController; -use Wnx\LaravelStats\Tests\Stubs\Controllers\ProjectsController; -use Wnx\LaravelStats\Tests\Stubs\Controllers\UsersController; use Wnx\LaravelStats\Tests\Stubs\Models\Group; use Wnx\LaravelStats\Tests\Stubs\Models\User; use Wnx\LaravelStats\Tests\TestCase; From 322e71a9cb95cccdbd8f49edbb8e435b48a7793a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Fri, 10 Jul 2020 18:48:40 +0200 Subject: [PATCH 052/103] Add more Stubs Controllers --- tests/Stubs/Controllers/BaseController.php | 12 +++++++++++ tests/Stubs/Controllers/PostsController.php | 23 +++++++++++++++++++++ 2 files changed, 35 insertions(+) create mode 100644 tests/Stubs/Controllers/BaseController.php create mode 100644 tests/Stubs/Controllers/PostsController.php diff --git a/tests/Stubs/Controllers/BaseController.php b/tests/Stubs/Controllers/BaseController.php new file mode 100644 index 00000000..8dddb392 --- /dev/null +++ b/tests/Stubs/Controllers/BaseController.php @@ -0,0 +1,12 @@ + Date: Fri, 10 Jul 2020 18:48:59 +0200 Subject: [PATCH 053/103] Add --name option --- src/Console/StatsListCommand.php | 40 ++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 73f42563..225f6f79 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -21,7 +21,11 @@ class StatsListCommand extends Command * * @var string */ - protected $signature = 'stats {--json : Output the statistics as JSON} {-c|--components= : Comma separated list of components which should be displayed} {--s|share : Share project statistic with Laravel community }'; + protected $signature = 'stats + {--json : Output the statistics as JSON} + {-c|--components= : Comma separated list of components which should be displayed} + {--s|share : Share project statistic with Laravel community } + {--name= : The name used when sharing project statistics}'; /** * The console command description. @@ -46,7 +50,7 @@ public function handle() return new ReflectionClass($class); })->reject(function (ReflectionClass $class) { return app(config('stats.rejection_strategy', RejectVendorClasses::class)) - ->shouldClassBeRejected($class); + ->shouldClassBeRejected($class); })->reject(function (ReflectionClass $class) { foreach (config('stats.ignored_namespaces', []) as $namespace) { if (Str::startsWith($class->getNamespaceName(), $namespace)) { @@ -72,7 +76,7 @@ private function getArrayOfComponentsToDisplay(): array return []; } - return explode(',', $this->option('components')); + return explode(',', $this->option('components')); } private function renderOutput(Project $project) @@ -98,7 +102,7 @@ private function shareDataWithShift(Project $project): void { $metrics = app(CollectMetrics::class)->collect($project); - $this->info("\n\n"); + $this->info("\n"); $this->info("The following metrics will be shared with stats.laravelshift.com."); $this->table( ['Name', 'Value'], @@ -106,15 +110,8 @@ private function shareDataWithShift(Project $project): void ); if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { - if (app(ProjectName::class)->hasStoredProjectName() === false) { - $generatedProjectName = app(ProjectName::class)->determineProjectNameFromGit(); - $projectName = $this->ask("We've determined the following name for your project. Do you want to rename it?", $generatedProjectName); - - app(ProjectName::class)->storeNameInRcFile($projectName); - } else { - $projectName = app(ProjectName::class)->get(); - } + $projectName = $this->getProjectName(); if ($projectName === null) { $this->error("Please provide a project name."); @@ -139,4 +136,23 @@ private function shareDataWithShift(Project $project): void } } } + + private function getProjectName(): ?string + { + if ($this->option('name')) { + return $this->option('name'); + } + + if (app(ProjectName::class)->hasStoredProjectName() === false) { + $generatedProjectName = app(ProjectName::class)->determineProjectNameFromGit(); + + $projectName = $this->ask("We've determined the following name for your project. Do you want to rename it?", $generatedProjectName); + + app(ProjectName::class)->storeNameInRcFile($projectName); + + return $projectName; + } + + return app(ProjectName::class)->get(); + } } From 7fd47969697cf4eb3486808d78d8fec7ca6fa983 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Fri, 10 Jul 2020 19:54:27 +0200 Subject: [PATCH 054/103] Rename Metric --- src/ShareableMetrics/CollectMetrics.php | 4 ++-- ...uardedOrFillable.php => ModelsMassAssignment.php} | 4 ++-- ...FillableTest.php => ModelsMassAssignmentTest.php} | 12 ++++++------ 3 files changed, 10 insertions(+), 10 deletions(-) rename src/ShareableMetrics/Metrics/{ModelsUseGuardedOrFillable.php => ModelsMassAssignment.php} (92%) rename tests/ShareableMetrics/Metrics/{ModelsUseGuardedOrFillableTest.php => ModelsMassAssignmentTest.php} (72%) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 6f7ebf74..14b699d0 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -11,7 +11,7 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsExtendOtherModel; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsMassAssignment; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; @@ -38,7 +38,7 @@ protected function getProjectMetrics(Project $project): Collection ProjectLinesOfCode::class, ProjectLogicalLinesOfCode::class, ProjectNumberOfClasses::class, - ModelsUseGuardedOrFillable::class, + ModelsMassAssignment::class, ControllersFormRequestInjection::class, CodeTestRatio::class, ModelsFolder::class, diff --git a/src/ShareableMetrics/Metrics/ModelsUseGuardedOrFillable.php b/src/ShareableMetrics/Metrics/ModelsMassAssignment.php similarity index 92% rename from src/ShareableMetrics/Metrics/ModelsUseGuardedOrFillable.php rename to src/ShareableMetrics/Metrics/ModelsMassAssignment.php index d60a7a32..5f864acc 100644 --- a/src/ShareableMetrics/Metrics/ModelsUseGuardedOrFillable.php +++ b/src/ShareableMetrics/Metrics/ModelsMassAssignment.php @@ -6,11 +6,11 @@ use Wnx\LaravelStats\Contracts\CollectableMetric; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; -class ModelsUseGuardedOrFillable extends Metric implements CollectableMetric +class ModelsMassAssignment extends Metric implements CollectableMetric { public function name(): string { - return 'models_guarded_fillable'; + return 'models_mass_assignment'; } public function value() diff --git a/tests/ShareableMetrics/Metrics/ModelsUseGuardedOrFillableTest.php b/tests/ShareableMetrics/Metrics/ModelsMassAssignmentTest.php similarity index 72% rename from tests/ShareableMetrics/Metrics/ModelsUseGuardedOrFillableTest.php rename to tests/ShareableMetrics/Metrics/ModelsMassAssignmentTest.php index e680f427..b2095d0d 100644 --- a/tests/ShareableMetrics/Metrics/ModelsUseGuardedOrFillableTest.php +++ b/tests/ShareableMetrics/Metrics/ModelsMassAssignmentTest.php @@ -2,22 +2,22 @@ namespace Wnx\LaravelStats\Tests\ShareableMetrics\Metrics; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsUseGuardedOrFillable; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsMassAssignment; use Wnx\LaravelStats\Tests\Stubs\Models\Group; use Wnx\LaravelStats\Tests\Stubs\Models\Post; use Wnx\LaravelStats\Tests\Stubs\Models\User; use Wnx\LaravelStats\Tests\TestCase; -class ModelsUseGuardedOrFillableTest extends TestCase +class ModelsMassAssignmentTest extends TestCase { /** @test */ public function it_returns_correct_metric_name() { $project = $this->createProjectFromClasses([]); - $metric = new ModelsUseGuardedOrFillable($project); + $metric = new ModelsMassAssignment($project); - $this->assertEquals('models_guarded_fillable', $metric->name()); + $this->assertEquals('models_mass_assignment', $metric->name()); } /** @test */ @@ -25,7 +25,7 @@ public function it_returns_an_empty_array_if_project_does_not_contain_models() { $project = $this->createProjectFromClasses([]); - $metric = new ModelsUseGuardedOrFillable($project); + $metric = new ModelsMassAssignment($project); $this->assertEquals([], $metric->value()); } @@ -39,7 +39,7 @@ public function it_returns_the_number_of_guarded_and_unguarded_models_in_the_ret Group::class ]); - $metric = new ModelsUseGuardedOrFillable($project); + $metric = new ModelsMassAssignment($project); $this->assertEquals([ 'guarded' => 1, From 0791eeccdce37e15aa24ddac31690a0f83ef8c1b Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Fri, 10 Jul 2020 19:56:22 +0200 Subject: [PATCH 055/103] Allow stats command to make requests to shift --- src/Console/StatsListCommand.php | 7 ++----- src/ShareableMetrics/SendToLaravelShift.php | 2 -- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 225f6f79..5945fdad 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -122,13 +122,10 @@ private function shareDataWithShift(Project $project): void $response = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); - dd( - $response->status(), - $response->body() - ); - if ($response->failed()) { $this->error("An error occured while transmitting data to laravelshift.com. Please try again."); + + dd($response->body()); } if ($response->successful()) { diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index 1056d1ca..a3eba01f 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -11,8 +11,6 @@ public function send(array $payload): Response { info('Send laravel-stats data to Laravel Shift', $payload); - dd($payload); - return Http::withHeaders([ 'Accept' => 'application/json' ])->post('https://laravelshift.com/api/stat', $payload); From 4ca194bee6f2a4d19a16a5fae1cb7f63728df721 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Fri, 10 Jul 2020 20:35:53 +0200 Subject: [PATCH 056/103] Update ModelsCustomInheritance.php --- src/ShareableMetrics/CollectMetrics.php | 4 ++-- ...dOtherModel.php => ModelsCustomInheritance.php} | 14 ++++++++++++-- ...delTest.php => ModelsCustomInheritanceTest.php} | 14 +++++++------- 3 files changed, 21 insertions(+), 11 deletions(-) rename src/ShareableMetrics/Metrics/{ModelsExtendOtherModel.php => ModelsCustomInheritance.php} (67%) rename tests/ShareableMetrics/Metrics/{ModelsExtendOtherModelTest.php => ModelsCustomInheritanceTest.php} (72%) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 14b699d0..91a3da88 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -9,7 +9,7 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\CodeTestRatio; use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllersFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsExtendOtherModel; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsCustomInheritance; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsMassAssignment; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; @@ -42,7 +42,7 @@ protected function getProjectMetrics(Project $project): Collection ControllersFormRequestInjection::class, CodeTestRatio::class, ModelsFolder::class, - ModelsExtendOtherModel::class, + ModelsCustomInheritance::class, ])->map(function ($statClass) use ($project) { return new $statClass($project); }); diff --git a/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php b/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php similarity index 67% rename from src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php rename to src/ShareableMetrics/Metrics/ModelsCustomInheritance.php index 04349fb9..5800a769 100644 --- a/src/ShareableMetrics/Metrics/ModelsExtendOtherModel.php +++ b/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php @@ -4,13 +4,14 @@ use Illuminate\Support\Str; use Wnx\LaravelStats\Contracts\CollectableMetric; +use Wnx\LaravelStats\ReflectionClass; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; -class ModelsExtendOtherModel extends Metric implements CollectableMetric +class ModelsCustomInheritance extends Metric implements CollectableMetric { public function name(): string { - return 'models_extend_model'; + return 'models_custom_inheritance'; } public function value() @@ -26,7 +27,16 @@ public function value() } return $models + + // Remove Models, which extend a Class which is located in the vendor folder + ->reject(function (ClassifiedClass $classifiedClass) { + + $parentclass = new ReflectionClass($classifiedClass->reflectionClass->getParentClass()->getName()); + + return $parentclass->isVendorProvided(); + }) ->reject(function (ClassifiedClass $classifiedClass) { + $parentClassName = $classifiedClass->reflectionClass->getParentClass()->getName(); // If a Model extends an Illuminate-class, remove it from the collection diff --git a/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php b/tests/ShareableMetrics/Metrics/ModelsCustomInheritanceTest.php similarity index 72% rename from tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php rename to tests/ShareableMetrics/Metrics/ModelsCustomInheritanceTest.php index e3313b42..592e6628 100644 --- a/tests/ShareableMetrics/Metrics/ModelsExtendOtherModelTest.php +++ b/tests/ShareableMetrics/Metrics/ModelsCustomInheritanceTest.php @@ -2,21 +2,21 @@ namespace Wnx\LaravelStats\Tests\ShareableMetrics\Metrics; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsExtendOtherModel; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsCustomInheritance; use Wnx\LaravelStats\Tests\Stubs\Models\Group; use Wnx\LaravelStats\Tests\Stubs\Models\User; use Wnx\LaravelStats\Tests\TestCase; -class ModelsExtendOtherModelTest extends TestCase +class ModelsCustomInheritanceTest extends TestCase { /** @test */ public function it_returns_correct_metric_name() { $project = $this->createProjectFromClasses([]); - $metric = new ModelsExtendOtherModel($project); + $metric = new ModelsCustomInheritance($project); - $this->assertEquals('models_extend_model', $metric->name()); + $this->assertEquals('models_custom_inheritance', $metric->name()); } /** @test */ @@ -26,7 +26,7 @@ public function it_returns_null_if_no_models_are_found_in_the_project() // ]); - $metric = new ModelsExtendOtherModel($project); + $metric = new ModelsCustomInheritance($project); $this->assertNull($metric->value()); } @@ -39,7 +39,7 @@ public function it_returns_true_if_models_extends_another_model_in_the_project() Group::class ]); - $metric = new ModelsExtendOtherModel($project); + $metric = new ModelsCustomInheritance($project); $this->assertTrue($metric->value()); } @@ -51,7 +51,7 @@ public function it_returns_false_if_models_does_not_extend_another_model_in_the_ User::class ]); - $metric = new ModelsExtendOtherModel($project); + $metric = new ModelsCustomInheritance($project); $this->assertFalse($metric->value()); } From 982b0f0ff79762e4b3240a50c39773b3efd23573 Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Fri, 10 Jul 2020 18:36:31 +0000 Subject: [PATCH 057/103] Apply php-cs-fixer changes --- src/Console/StatsListCommand.php | 1 - src/ShareableMetrics/Metrics/ModelsCustomInheritance.php | 2 -- 2 files changed, 3 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 5945fdad..8516867d 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -110,7 +110,6 @@ private function shareDataWithShift(Project $project): void ); if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { - $projectName = $this->getProjectName(); if ($projectName === null) { diff --git a/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php b/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php index 5800a769..90549570 100644 --- a/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php +++ b/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php @@ -30,13 +30,11 @@ public function value() // Remove Models, which extend a Class which is located in the vendor folder ->reject(function (ClassifiedClass $classifiedClass) { - $parentclass = new ReflectionClass($classifiedClass->reflectionClass->getParentClass()->getName()); return $parentclass->isVendorProvided(); }) ->reject(function (ClassifiedClass $classifiedClass) { - $parentClassName = $classifiedClass->reflectionClass->getParentClass()->getName(); // If a Model extends an Illuminate-class, remove it from the collection From 1b263f0a187e9383b84a00709d2dea2cbcca7f3e Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Fri, 10 Jul 2020 20:47:22 +0200 Subject: [PATCH 058/103] Sort Metrics displayed in ASCII Table --- src/ShareableMetrics/MetricsCollection.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php index 809f7bd7..56eaa78a 100644 --- a/src/ShareableMetrics/MetricsCollection.php +++ b/src/ShareableMetrics/MetricsCollection.php @@ -23,7 +23,8 @@ public function toAsciiTableFormat(): array } return $metric; - }); + }) + ->sort(); return $projectMetrics ->forget('packages') From 9c0d3685ee279e10c4d537252f4292cc818d5b0c Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 11 Jul 2020 15:39:28 +0200 Subject: [PATCH 059/103] Add ScheduledTasks Metric --- src/ShareableMetrics/CollectMetrics.php | 2 + .../Metrics/ScheduledTasks.php | 20 +++++++++ .../Metrics/ScheduledTasksTest.php | 45 +++++++++++++++++++ 3 files changed, 67 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/ScheduledTasks.php create mode 100644 tests/ShareableMetrics/Metrics/ScheduledTasksTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 91a3da88..5915274b 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -14,6 +14,7 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsMassAssignment; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ScheduledTasks; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLogicalLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectNumberOfClasses; @@ -33,6 +34,7 @@ protected function getProjectMetrics(Project $project): Collection { $availableMetrics = collect([ InstalledPackages::class, + ScheduledTasks::class, NumberOfRelationships::class, NumberOfRoutes::class, ProjectLinesOfCode::class, diff --git a/src/ShareableMetrics/Metrics/ScheduledTasks.php b/src/ShareableMetrics/Metrics/ScheduledTasks.php new file mode 100644 index 00000000..56223a6a --- /dev/null +++ b/src/ShareableMetrics/Metrics/ScheduledTasks.php @@ -0,0 +1,20 @@ +events()); + } +} diff --git a/tests/ShareableMetrics/Metrics/ScheduledTasksTest.php b/tests/ShareableMetrics/Metrics/ScheduledTasksTest.php new file mode 100644 index 00000000..72e9c202 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ScheduledTasksTest.php @@ -0,0 +1,45 @@ +createProjectFromClasses([]); + + $metric = new ScheduledTasks($project); + + $this->assertEquals('scheduled_tasks', $metric->name()); + } + + /** @test */ + public function it_returns_0_if_no_scheduled_tasks_can_be_found() + { + $project = $this->createProjectFromClasses([]); + + $metric = new ScheduledTasks($project); + + $this->assertEquals(0, $metric->value()); + } + + /** @test */ + public function it_returns_correct_number_of_scheduled_tasks() + { + app(Schedule::class)->command('inspire')->hourly(); + app(Schedule::class)->call(function () { + // Don't panic! + })->daily(); + + $project = $this->createProjectFromClasses([]); + + $metric = new ScheduledTasks($project); + + $this->assertEquals(2, $metric->value()); + } +} From c9f7e9c97444e1abe03ef1e7313b902d21b2e7a3 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 11 Jul 2020 15:59:20 +0200 Subject: [PATCH 060/103] Add ComposerPsr4Sources --- src/ShareableMetrics/CollectMetrics.php | 2 + .../Metrics/ComposerPsr4Sources.php | 24 ++++++++++++ .../Metrics/ComposerPsr4SourcesTest.php | 37 +++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/ComposerPsr4Sources.php create mode 100644 tests/ShareableMetrics/Metrics/ComposerPsr4SourcesTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 5915274b..8d8caa5d 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -7,6 +7,7 @@ use Wnx\LaravelStats\Classifier; use Wnx\LaravelStats\Project; use Wnx\LaravelStats\ShareableMetrics\Metrics\CodeTestRatio; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ComposerPsr4Sources; use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllersFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsCustomInheritance; @@ -36,6 +37,7 @@ protected function getProjectMetrics(Project $project): Collection InstalledPackages::class, ScheduledTasks::class, NumberOfRelationships::class, + ComposerPsr4Sources::class, NumberOfRoutes::class, ProjectLinesOfCode::class, ProjectLogicalLinesOfCode::class, diff --git a/src/ShareableMetrics/Metrics/ComposerPsr4Sources.php b/src/ShareableMetrics/Metrics/ComposerPsr4Sources.php new file mode 100644 index 00000000..5ea4c284 --- /dev/null +++ b/src/ShareableMetrics/Metrics/ComposerPsr4Sources.php @@ -0,0 +1,24 @@ +createProjectFromClasses([]); + + $metric = new ComposerPsr4Sources($project); + + $this->assertEquals('composer_psr_4_namespaces', $metric->name()); + } + + /** @test */ + public function it_returns_composer_psr_4_sources() + { + $project = $this->createProjectFromClasses([]); + + $metric = new ComposerPsr4Sources($project); + + $value = $metric->value(); + + $this->assertIsArray($value); + + // dd($value); + + $this->assertEquals([ + "App\\" => 'app/' + ], $value); + } +} From b23455746c54fa85a14cdc08074c3d1b351f04b4 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 11 Jul 2020 16:15:12 +0200 Subject: [PATCH 061/103] Add ControllersCustomInheritance --- src/ShareableMetrics/CollectMetrics.php | 2 + .../Metrics/ControllersCustomInheritance.php | 47 +++++++++++++ .../ControllersCustomInheritanceTest.php | 66 +++++++++++++++++++ 3 files changed, 115 insertions(+) create mode 100644 src/ShareableMetrics/Metrics/ControllersCustomInheritance.php create mode 100644 tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 8d8caa5d..d662b9a4 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -8,6 +8,7 @@ use Wnx\LaravelStats\Project; use Wnx\LaravelStats\ShareableMetrics\Metrics\CodeTestRatio; use Wnx\LaravelStats\ShareableMetrics\Metrics\ComposerPsr4Sources; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllersCustomInheritance; use Wnx\LaravelStats\ShareableMetrics\Metrics\ControllersFormRequestInjection; use Wnx\LaravelStats\ShareableMetrics\Metrics\InstalledPackages; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsCustomInheritance; @@ -44,6 +45,7 @@ protected function getProjectMetrics(Project $project): Collection ProjectNumberOfClasses::class, ModelsMassAssignment::class, ControllersFormRequestInjection::class, + ControllersCustomInheritance::class, CodeTestRatio::class, ModelsFolder::class, ModelsCustomInheritance::class, diff --git a/src/ShareableMetrics/Metrics/ControllersCustomInheritance.php b/src/ShareableMetrics/Metrics/ControllersCustomInheritance.php new file mode 100644 index 00000000..352236a2 --- /dev/null +++ b/src/ShareableMetrics/Metrics/ControllersCustomInheritance.php @@ -0,0 +1,47 @@ +project + ->classifiedClasses() + ->filter(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->classifier->name() === 'Controllers'; + }); + + if ($controllers->count() === 0) { + return null; + } + + return $controllers + ->reject(function (ClassifiedClass $classifiedClass) { + return $classifiedClass->reflectionClass->getParentClass() === false; + }) + + // Remove Controllers, which extend a Class which is located in the vendor folder + ->reject(function (ClassifiedClass $classifiedClass) { + $parentclass = new ReflectionClass($classifiedClass->reflectionClass->getParentClass()->getName()); + + return $parentclass->isVendorProvided(); + }) + ->reject(function (ClassifiedClass $classifiedClass) { + + $parentClassName = $classifiedClass->reflectionClass->getParentClass()->getShortName(); + + return $parentClassName === 'Controller'; + }) + ->count() > 0; + } +} diff --git a/tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php b/tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php new file mode 100644 index 00000000..54b98ee8 --- /dev/null +++ b/tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php @@ -0,0 +1,66 @@ +createProjectFromClasses([]); + + $metric = new ControllersCustomInheritance($project); + + $this->assertEquals('controllers_custom_inheritance', $metric->name()); + } + + /** @test */ + public function it_returns_true_if_controller_extends_another_controller_in_the_project() + { + Route::get('posts', [PostsController::class, 'index']); + + $project = $this->createProjectFromClasses([ + PostsController::class + ]); + + $metric = new ControllersCustomInheritance($project); + + $this->assertTrue($metric->value()); + } + + /** @test */ + public function it_returns_false_if_controller_does_not_extend_another_controller_in_the_project() + { + Route::get('projects', [ProjectsController::class, 'index']); + + $project = $this->createProjectFromClasses([ + ProjectsController::class + ]); + + $metric = new ControllersCustomInheritance($project); + + $this->assertFalse($metric->value()); + } + + /** @test */ + public function it_returns_false_if_controller_extends_the_default_laravel_controller() + { + Route::get('users', [UsersController::class, 'index']); + + $project = $this->createProjectFromClasses([ + UsersController::class + ]); + + $metric = new ControllersCustomInheritance($project); + + $this->assertFalse($metric->value()); + } + +} From 2073363566002e16834deb017f913ce7ad9bb59d Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 11 Jul 2020 16:21:58 +0200 Subject: [PATCH 062/103] Rename ModelRelationship Metric --- src/ShareableMetrics/CollectMetrics.php | 4 ++-- ...umberOfRelationships.php => ModelRelationships.php} | 5 ++--- ...elationshipsTest.php => ModelRelationshipsTest.php} | 10 +++++----- 3 files changed, 9 insertions(+), 10 deletions(-) rename src/ShareableMetrics/Metrics/{NumberOfRelationships.php => ModelRelationships.php} (86%) rename tests/ShareableMetrics/Metrics/{NumberOfRelationshipsTest.php => ModelRelationshipsTest.php} (78%) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index d662b9a4..1cd55c5a 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -14,7 +14,7 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsCustomInheritance; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsMassAssignment; -use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ScheduledTasks; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; @@ -37,7 +37,7 @@ protected function getProjectMetrics(Project $project): Collection $availableMetrics = collect([ InstalledPackages::class, ScheduledTasks::class, - NumberOfRelationships::class, + ModelRelationships::class, ComposerPsr4Sources::class, NumberOfRoutes::class, ProjectLinesOfCode::class, diff --git a/src/ShareableMetrics/Metrics/NumberOfRelationships.php b/src/ShareableMetrics/Metrics/ModelRelationships.php similarity index 86% rename from src/ShareableMetrics/Metrics/NumberOfRelationships.php rename to src/ShareableMetrics/Metrics/ModelRelationships.php index aa79cb6f..bed1120e 100644 --- a/src/ShareableMetrics/Metrics/NumberOfRelationships.php +++ b/src/ShareableMetrics/Metrics/ModelRelationships.php @@ -6,7 +6,7 @@ use Wnx\LaravelStats\Contracts\CollectableMetric; use Wnx\LaravelStats\ValueObjects\ClassifiedClass; -class NumberOfRelationships extends Metric implements CollectableMetric +class ModelRelationships extends Metric implements CollectableMetric { public function name(): string { @@ -20,10 +20,9 @@ public function value() ->filter(function (ClassifiedClass $classifiedClass) { return $classifiedClass->classifier->name() === 'Models'; }) - ->map(function (ClassifiedClass $classifiedClass) { + ->flatMap(function (ClassifiedClass $classifiedClass) { return $classifiedClass->reflectionClass->getMethods(); }) - ->flatten(1) ->filter(function (\ReflectionMethod $method) { return $method->hasReturnType(); }) diff --git a/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php b/tests/ShareableMetrics/Metrics/ModelRelationshipsTest.php similarity index 78% rename from tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php rename to tests/ShareableMetrics/Metrics/ModelRelationshipsTest.php index 55ed8682..7359e8e5 100644 --- a/tests/ShareableMetrics/Metrics/NumberOfRelationshipsTest.php +++ b/tests/ShareableMetrics/Metrics/ModelRelationshipsTest.php @@ -2,20 +2,20 @@ namespace Wnx\LaravelStats\Tests\ShareableMetrics\Metrics; -use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRelationships; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelRelationships; use Wnx\LaravelStats\Tests\Stubs\Models\Group; use Wnx\LaravelStats\Tests\Stubs\Models\Post; use Wnx\LaravelStats\Tests\Stubs\Models\User; use Wnx\LaravelStats\Tests\TestCase; -class NumberOfRelationshipsTest extends TestCase +class ModelRelationshipsTest extends TestCase { /** @test */ public function it_returns_correct_metric_name() { $project = $this->createProjectFromClasses([]); - $metric = new NumberOfRelationships($project); + $metric = new ModelRelationships($project); $this->assertEquals('models_relationships', $metric->name()); } @@ -25,7 +25,7 @@ public function it_returns_0_if_no_relationships_could_be_found_for_a_given_proj { $project = $this->createProjectFromClasses([]); - $metric = new NumberOfRelationships($project); + $metric = new ModelRelationships($project); $this->assertEquals(0, $metric->value()); } @@ -39,7 +39,7 @@ public function it_returns_correct_number_of_relationships_in_a_project_for_a_gi Group::class ]); - $metric = new NumberOfRelationships($project); + $metric = new ModelRelationships($project); $this->assertEquals(5, $metric->value()); } From 3ff721ee6f5c6e896fb4fd9e6d6a5c2940255261 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 11 Jul 2020 16:22:46 +0200 Subject: [PATCH 063/103] Sort Metrics --- src/ShareableMetrics/CollectMetrics.php | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 1cd55c5a..c456811e 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -35,20 +35,20 @@ public function collect(Project $project): MetricsCollection protected function getProjectMetrics(Project $project): Collection { $availableMetrics = collect([ + CodeTestRatio::class, + ComposerPsr4Sources::class, + ControllersCustomInheritance::class, + ControllersFormRequestInjection::class, InstalledPackages::class, - ScheduledTasks::class, ModelRelationships::class, - ComposerPsr4Sources::class, + ModelsCustomInheritance::class, + ModelsFolder::class, + ModelsMassAssignment::class, NumberOfRoutes::class, ProjectLinesOfCode::class, ProjectLogicalLinesOfCode::class, ProjectNumberOfClasses::class, - ModelsMassAssignment::class, - ControllersFormRequestInjection::class, - ControllersCustomInheritance::class, - CodeTestRatio::class, - ModelsFolder::class, - ModelsCustomInheritance::class, + ScheduledTasks::class, ])->map(function ($statClass) use ($project) { return new $statClass($project); }); From 477f418caec6e55de30d64c111c9d5a0df2ecd0b Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 11 Jul 2020 16:23:37 +0200 Subject: [PATCH 064/103] Remove a Test --- .../Metrics/ModelsFolderTest.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tests/ShareableMetrics/Metrics/ModelsFolderTest.php b/tests/ShareableMetrics/Metrics/ModelsFolderTest.php index da76b2ec..badc0083 100644 --- a/tests/ShareableMetrics/Metrics/ModelsFolderTest.php +++ b/tests/ShareableMetrics/Metrics/ModelsFolderTest.php @@ -30,21 +30,7 @@ public function it_returns_null_if_no_models_are_found_in_the_project() $this->assertNull($metric->value()); } - - /** @test */ - public function it_returns_false_if_models_are_stored_in_default_namespace() - { - $this->markTestIncomplete("Need to add Model under correct namespace for testing"); - - $project = $this->createProjectFromClasses([ - // Model located under App\ - ]); - - $metric = new ModelsFolder($project); - - $this->assertFalse($metric->value()); - } - + /** @test */ public function it_returns_true_if_models_are_stored_in_non_default_namespace() { From 76fa45b1736b3518c706e45d25ef70a008e91b0a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Sat, 11 Jul 2020 16:35:14 +0200 Subject: [PATCH 065/103] Fixes in ControllersFormRequestInjection --- .../Metrics/ControllersFormRequestInjection.php | 3 +++ tests/Stubs/Controllers/UsersController.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ShareableMetrics/Metrics/ControllersFormRequestInjection.php b/src/ShareableMetrics/Metrics/ControllersFormRequestInjection.php index 20947170..3f74681f 100644 --- a/src/ShareableMetrics/Metrics/ControllersFormRequestInjection.php +++ b/src/ShareableMetrics/Metrics/ControllersFormRequestInjection.php @@ -35,6 +35,9 @@ public function value() ->filter(function (ReflectionParameter $param) { return $param->hasType(); }) + ->reject(function (ReflectionParameter $param) { + return $param->getType()->isBuiltin(); + }) ->filter(function (ReflectionParameter $param) { $reflectionClass = new ReflectionClass($param->getType()->getName()); diff --git a/tests/Stubs/Controllers/UsersController.php b/tests/Stubs/Controllers/UsersController.php index 88b56c6b..5c573bd1 100644 --- a/tests/Stubs/Controllers/UsersController.php +++ b/tests/Stubs/Controllers/UsersController.php @@ -6,7 +6,7 @@ class UsersController extends Controller { - public function index() + public function index(array $filter = []) { return []; } From 2955c6a2d446d7f92242b54e8e9ddafbaf5392ec Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Sat, 11 Jul 2020 14:35:49 +0000 Subject: [PATCH 066/103] Apply php-cs-fixer changes --- src/ShareableMetrics/Metrics/ControllersCustomInheritance.php | 1 - src/ShareableMetrics/Metrics/ScheduledTasks.php | 1 - tests/Console/StatsListCommandTest.php | 1 - .../Metrics/ControllersCustomInheritanceTest.php | 1 - tests/ShareableMetrics/Metrics/ModelsFolderTest.php | 1 - 5 files changed, 5 deletions(-) diff --git a/src/ShareableMetrics/Metrics/ControllersCustomInheritance.php b/src/ShareableMetrics/Metrics/ControllersCustomInheritance.php index 352236a2..f9dd2a6f 100644 --- a/src/ShareableMetrics/Metrics/ControllersCustomInheritance.php +++ b/src/ShareableMetrics/Metrics/ControllersCustomInheritance.php @@ -37,7 +37,6 @@ public function value() return $parentclass->isVendorProvided(); }) ->reject(function (ClassifiedClass $classifiedClass) { - $parentClassName = $classifiedClass->reflectionClass->getParentClass()->getShortName(); return $parentClassName === 'Controller'; diff --git a/src/ShareableMetrics/Metrics/ScheduledTasks.php b/src/ShareableMetrics/Metrics/ScheduledTasks.php index 56223a6a..17a0497d 100644 --- a/src/ShareableMetrics/Metrics/ScheduledTasks.php +++ b/src/ShareableMetrics/Metrics/ScheduledTasks.php @@ -4,7 +4,6 @@ use Illuminate\Console\Scheduling\Schedule; use Wnx\LaravelStats\Contracts\CollectableMetric; -use Wnx\LaravelStats\ValueObjects\ClassifiedClass; class ScheduledTasks extends Metric implements CollectableMetric { diff --git a/tests/Console/StatsListCommandTest.php b/tests/Console/StatsListCommandTest.php index fea333b7..52eead06 100644 --- a/tests/Console/StatsListCommandTest.php +++ b/tests/Console/StatsListCommandTest.php @@ -2,7 +2,6 @@ namespace Wnx\LaravelStats\Tests\Console; -use Wnx\LaravelStats\Tests\Stubs\Mails\DemoMail; use Wnx\LaravelStats\Tests\TestCase; use Illuminate\Support\Facades\Route; use Illuminate\Support\Facades\Artisan; diff --git a/tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php b/tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php index 54b98ee8..7dc1637d 100644 --- a/tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php +++ b/tests/ShareableMetrics/Metrics/ControllersCustomInheritanceTest.php @@ -62,5 +62,4 @@ public function it_returns_false_if_controller_extends_the_default_laravel_contr $this->assertFalse($metric->value()); } - } diff --git a/tests/ShareableMetrics/Metrics/ModelsFolderTest.php b/tests/ShareableMetrics/Metrics/ModelsFolderTest.php index badc0083..5d8bef5f 100644 --- a/tests/ShareableMetrics/Metrics/ModelsFolderTest.php +++ b/tests/ShareableMetrics/Metrics/ModelsFolderTest.php @@ -2,7 +2,6 @@ namespace Wnx\LaravelStats\Tests\ShareableMetrics\Metrics; -use Illuminate\Database\Eloquent\Model; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\Tests\Stubs\Models\User; use Wnx\LaravelStats\Tests\TestCase; From e6b9b570a6b3a560b7c1cc69aa9007b4c7a657de Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Tue, 14 Jul 2020 13:26:12 -0400 Subject: [PATCH 067/103] Tweak package name for testing --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3f1c4dd0..9b807ee6 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "wnx/laravel-stats", + "name": "stefanzweifel/laravel-stats-metrics-feature", "description": "Get insights about your Laravel Project", "homepage": "https://github.com/stefanzweifel/laravel-stats", "keywords": ["laravel", "wnx", "statistics", "stats"], From 370901d787e67fb108a18e1703c15869d6917752 Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Tue, 14 Jul 2020 13:49:44 -0400 Subject: [PATCH 068/103] Revert "Tweak package name for testing" This reverts commit e6b9b570a6b3a560b7c1cc69aa9007b4c7a657de. --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 9b807ee6..3f1c4dd0 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "stefanzweifel/laravel-stats-metrics-feature", + "name": "wnx/laravel-stats", "description": "Get insights about your Laravel Project", "homepage": "https://github.com/stefanzweifel/laravel-stats", "keywords": ["laravel", "wnx", "statistics", "stats"], From 6bafb2c9abb88421e92044bd5d02cdf4be2bd6a9 Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Tue, 14 Jul 2020 13:58:31 -0400 Subject: [PATCH 069/103] Lessen constraints to support Laravel 6 --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index 3f1c4dd0..62276a39 100644 --- a/composer.json +++ b/composer.json @@ -15,11 +15,11 @@ "require": { "php": ">=7.3.0", "ext-json": "*", - "illuminate/console": "^7.0", - "illuminate/support": "^7.0", - "phploc/phploc": "~6.0", - "symfony/finder": "~5.0", - "symfony/process": "~5.0" + "illuminate/console": "^6.0 || ^7.0", + "illuminate/support": "^6.0 || ^7.0", + "phploc/phploc": "^5.0 || ^6.0", + "symfony/finder": "^4.3 || ^5.0", + "symfony/process": "^4.3 || ^5.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.15", From 36eedd268ebd047b27cbb43042cfca6870987d8e Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 14 Jul 2020 21:06:00 +0200 Subject: [PATCH 070/103] Add a --no-send option --- src/Console/StatsListCommand.php | 34 ++++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 8516867d..a0643487 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -25,6 +25,7 @@ class StatsListCommand extends Command {--json : Output the statistics as JSON} {-c|--components= : Comma separated list of components which should be displayed} {--s|share : Share project statistic with Laravel community } + {--no-send : Do not send the project statistic to Shift} {--name= : The name used when sharing project statistics}'; /** @@ -81,7 +82,7 @@ private function getArrayOfComponentsToDisplay(): array private function renderOutput(Project $project) { - if ($this->option('json') === true) { + if ($this->option('json') === true && $this->option('share') !== true) { $json = (new JsonOutput())->render( $project, $this->option('verbose'), @@ -102,12 +103,9 @@ private function shareDataWithShift(Project $project): void { $metrics = app(CollectMetrics::class)->collect($project); - $this->info("\n"); - $this->info("The following metrics will be shared with stats.laravelshift.com."); - $this->table( - ['Name', 'Value'], - $metrics->toAsciiTableFormat() - ); + if ($this->option('json') === false) { + $this->renderMetricsAsciiTable($metrics); + } if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { $projectName = $this->getProjectName(); @@ -117,7 +115,17 @@ private function shareDataWithShift(Project $project): void return; } - $this->info("The project name '{$projectName}' will be used."); + if ($this->option('json') === false) { + $this->info("The project name '{$projectName}' will be used."); + } + + + $payload = $metrics->toHttpPayload($projectName); + + if ($this->option('no-send')) { + $this->output->text(json_encode($payload)); + return; + } $response = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); @@ -133,6 +141,16 @@ private function shareDataWithShift(Project $project): void } } + private function renderMetricsAsciiTable($metrics): void + { + $this->info("\n"); + $this->info("The following metrics will be shared with stats.laravelshift.com."); + $this->table( + ['Name', 'Value'], + $metrics->toAsciiTableFormat() + ); + } + private function getProjectName(): ?string { if ($this->option('name')) { From bda6cc01253ec8d1af98eb1b5ac192f53404364b Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 14 Jul 2020 21:07:31 +0200 Subject: [PATCH 071/103] Fix the --json --share output --- src/Console/StatsListCommand.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index a0643487..dbd62d3e 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -82,14 +82,16 @@ private function getArrayOfComponentsToDisplay(): array private function renderOutput(Project $project) { - if ($this->option('json') === true && $this->option('share') !== true) { + if ($this->option('json') === true) { $json = (new JsonOutput())->render( $project, $this->option('verbose'), $this->getArrayOfComponentsToDisplay() ); - $this->output->text(json_encode($json)); + if ($this->option('share') !== true) { + $this->output->text(json_encode($json)); + } } else { (new AsciiTableOutput($this->output))->render( $project, From 8592edfd3485806a31a0789b1fe82fa5c3bf78ff Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Tue, 14 Jul 2020 19:55:55 -0400 Subject: [PATCH 072/103] Reference fork of PHPLoC --- composer.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 62276a39..126a3742 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "ext-json": "*", "illuminate/console": "^6.0 || ^7.0", "illuminate/support": "^6.0 || ^7.0", - "phploc/phploc": "^5.0 || ^6.0", + "phploc/phploc": "dev-metrics", "symfony/finder": "^4.3 || ^5.0", "symfony/process": "^4.3 || ^5.0" }, @@ -55,5 +55,9 @@ "Wnx\\LaravelStats\\StatsServiceProvider" ] } - } + }, + "repositories": [{ + "type": "vcs", + "url": "git@github.com:stefanzweifel/phploc.git" + }] } From 11edc76bbf1e2dc1cba4ba137b3b1ebe549a330f Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Wed, 15 Jul 2020 12:25:58 -0400 Subject: [PATCH 073/103] Downgrade to Guzzle for Laravel 6 --- src/Console/StatsListCommand.php | 12 +--------- src/ShareableMetrics/SendToLaravelShift.php | 26 ++++++++++++++++----- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index dbd62d3e..19d683d0 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -129,17 +129,7 @@ private function shareDataWithShift(Project $project): void return; } - $response = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); - - if ($response->failed()) { - $this->error("An error occured while transmitting data to laravelshift.com. Please try again."); - - dd($response->body()); - } - - if ($response->successful()) { - $this->info("Thanks for sharing your project data with the community!"); - } + app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); } } diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index a3eba01f..ad049cd2 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -2,17 +2,31 @@ namespace Wnx\LaravelStats\ShareableMetrics; -use Illuminate\Http\Client\Response; -use Illuminate\Support\Facades\Http; +use GuzzleHttp\Client; +use GuzzleHttp\Exception\GuzzleException; class SendToLaravelShift { public function send(array $payload): Response { - info('Send laravel-stats data to Laravel Shift', $payload); + info('Sharing stats with stats.laravelshift.com', $payload); - return Http::withHeaders([ - 'Accept' => 'application/json' - ])->post('https://laravelshift.com/api/stat', $payload); + try { + $client = new Client([ + 'base_uri' => 'https://laravelshift.com', + 'timeout' => 1, + 'headers' => ['Accept' => 'application/json'], + ]); + + $response = $client->request('POST', '/api/stat', [ + 'json' => $payload, + ]); + } catch (GuzzleException $exception) { + error('unable to share stats: ' . $exception->getMessage()); + } + + if (in_array($response->getStatusCode(), [201, 204])) { + info("Thanks for sharing your project data with the community!"); + } } } From 8977878983dbf2ff540ba54137b774bde203c998 Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Wed, 15 Jul 2020 12:38:10 -0400 Subject: [PATCH 074/103] Downgrade Str::of for Laravel 6 --- src/Classifiers/ObserverClassifier.php | 4 ++-- src/ShareableMetrics/Metrics/ModelRelationships.php | 2 +- src/ShareableMetrics/Metrics/ModelsCustomInheritance.php | 2 +- src/ShareableMetrics/Metrics/ModelsFolder.php | 2 +- src/ShareableMetrics/ProjectName.php | 4 +--- 5 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/Classifiers/ObserverClassifier.php b/src/Classifiers/ObserverClassifier.php index f30443ab..22908fbe 100644 --- a/src/Classifiers/ObserverClassifier.php +++ b/src/Classifiers/ObserverClassifier.php @@ -20,7 +20,7 @@ public function satisfies(ReflectionClass $class): bool { return collect($this->getEvents()) ->filter(function ($listeners, $event) { - return Str::of($event)->startsWith('eloquent.'); + return Str::startsWith($event, 'eloquent.'); }) ->map(function ($listeners) { return collect($listeners)->map(function (Closure $closure) { @@ -30,7 +30,7 @@ public function satisfies(ReflectionClass $class): bool ->collapse() ->unique() ->filter(function ($eventListenerSignature) use ($class) { - return Str::of($eventListenerSignature)->contains($class->getName()); + return Str::contains($eventListenerSignature, $class->getName()); }) ->count() > 0; } diff --git a/src/ShareableMetrics/Metrics/ModelRelationships.php b/src/ShareableMetrics/Metrics/ModelRelationships.php index bed1120e..1d79970a 100644 --- a/src/ShareableMetrics/Metrics/ModelRelationships.php +++ b/src/ShareableMetrics/Metrics/ModelRelationships.php @@ -27,7 +27,7 @@ public function value() return $method->hasReturnType(); }) ->filter(function (\ReflectionMethod $method) { - return Str::of($method->getReturnType()->getName())->startsWith('Illuminate\Database\Eloquent\Relations'); + return Str::startsWith($method->getReturnType()->getName(), 'Illuminate\Database\Eloquent\Relations'); }) ->count(); } diff --git a/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php b/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php index 90549570..d0c43961 100644 --- a/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php +++ b/src/ShareableMetrics/Metrics/ModelsCustomInheritance.php @@ -39,7 +39,7 @@ public function value() // If a Model extends an Illuminate-class, remove it from the collection // as we see it as a "normal" Model - return Str::of($parentClassName)->startsWith('Illuminate'); + return Str::startsWith($parentClassName, 'Illuminate'); }) ->count() > 0; } diff --git a/src/ShareableMetrics/Metrics/ModelsFolder.php b/src/ShareableMetrics/Metrics/ModelsFolder.php index 487af95f..01d1f428 100644 --- a/src/ShareableMetrics/Metrics/ModelsFolder.php +++ b/src/ShareableMetrics/Metrics/ModelsFolder.php @@ -32,7 +32,7 @@ public function value() ->filter(function (string $namespace) { // If a Models namespace contains a back-slash, we assume that the Model // is not located in the default location under /app, but somewhere else - return Str::of($namespace)->contains("\\"); + return Str::contains($namespace, "\\"); }) ->count() > 0; } diff --git a/src/ShareableMetrics/ProjectName.php b/src/ShareableMetrics/ProjectName.php index 24a19f48..d50c903b 100644 --- a/src/ShareableMetrics/ProjectName.php +++ b/src/ShareableMetrics/ProjectName.php @@ -30,9 +30,7 @@ public function determineProjectNameFromGit(): ?string $remoteUrl = parse_url(trim($process->getOutput())); - return Str::of($remoteUrl['path']) - ->replaceFirst('/', '') - ->__toString(); + return Str::replaceFirst('/', '', $remoteUrl['path']); } protected function pathToRcFile(): string From 64696a3b88e8be22fa6755f4f65900d9b8757cdf Mon Sep 17 00:00:00 2001 From: Jason McCreary Date: Wed, 15 Jul 2020 12:41:18 -0400 Subject: [PATCH 075/103] Drop return type --- src/ShareableMetrics/SendToLaravelShift.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index ad049cd2..a135b111 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -7,7 +7,7 @@ class SendToLaravelShift { - public function send(array $payload): Response + public function send(array $payload): void { info('Sharing stats with stats.laravelshift.com', $payload); From 71d74d64500778f8a4859dd6bb4e3df7aad12f19 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 19:45:30 +0200 Subject: [PATCH 076/103] Delete ModelRelationships --- src/ShareableMetrics/CollectMetrics.php | 2 - .../Metrics/ModelRelationships.php | 34 -------------- .../Metrics/ModelRelationshipsTest.php | 46 ------------------- 3 files changed, 82 deletions(-) delete mode 100644 src/ShareableMetrics/Metrics/ModelRelationships.php delete mode 100644 tests/ShareableMetrics/Metrics/ModelRelationshipsTest.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index c456811e..8253e1e2 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -14,7 +14,6 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsCustomInheritance; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsMassAssignment; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelRelationships; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; use Wnx\LaravelStats\ShareableMetrics\Metrics\ScheduledTasks; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; @@ -40,7 +39,6 @@ protected function getProjectMetrics(Project $project): Collection ControllersCustomInheritance::class, ControllersFormRequestInjection::class, InstalledPackages::class, - ModelRelationships::class, ModelsCustomInheritance::class, ModelsFolder::class, ModelsMassAssignment::class, diff --git a/src/ShareableMetrics/Metrics/ModelRelationships.php b/src/ShareableMetrics/Metrics/ModelRelationships.php deleted file mode 100644 index 1d79970a..00000000 --- a/src/ShareableMetrics/Metrics/ModelRelationships.php +++ /dev/null @@ -1,34 +0,0 @@ -project - ->classifiedClasses() - ->filter(function (ClassifiedClass $classifiedClass) { - return $classifiedClass->classifier->name() === 'Models'; - }) - ->flatMap(function (ClassifiedClass $classifiedClass) { - return $classifiedClass->reflectionClass->getMethods(); - }) - ->filter(function (\ReflectionMethod $method) { - return $method->hasReturnType(); - }) - ->filter(function (\ReflectionMethod $method) { - return Str::startsWith($method->getReturnType()->getName(), 'Illuminate\Database\Eloquent\Relations'); - }) - ->count(); - } -} diff --git a/tests/ShareableMetrics/Metrics/ModelRelationshipsTest.php b/tests/ShareableMetrics/Metrics/ModelRelationshipsTest.php deleted file mode 100644 index 7359e8e5..00000000 --- a/tests/ShareableMetrics/Metrics/ModelRelationshipsTest.php +++ /dev/null @@ -1,46 +0,0 @@ -createProjectFromClasses([]); - - $metric = new ModelRelationships($project); - - $this->assertEquals('models_relationships', $metric->name()); - } - - /** @test */ - public function it_returns_0_if_no_relationships_could_be_found_for_a_given_project() - { - $project = $this->createProjectFromClasses([]); - - $metric = new ModelRelationships($project); - - $this->assertEquals(0, $metric->value()); - } - - /** @test */ - public function it_returns_correct_number_of_relationships_in_a_project_for_a_given_project() - { - $project = $this->createProjectFromClasses([ - User::class, - Post::class, - Group::class - ]); - - $metric = new ModelRelationships($project); - - $this->assertEquals(5, $metric->value()); - } -} From a55c6029873071ce451d090bca4a9ea29ba8b56a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 19:52:12 +0200 Subject: [PATCH 077/103] Do not render metrics as ASCII table --- src/Console/StatsListCommand.php | 14 ----------- src/ShareableMetrics/MetricsCollection.php | 27 ---------------------- 2 files changed, 41 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 19d683d0..1fc27bfd 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -105,10 +105,6 @@ private function shareDataWithShift(Project $project): void { $metrics = app(CollectMetrics::class)->collect($project); - if ($this->option('json') === false) { - $this->renderMetricsAsciiTable($metrics); - } - if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { $projectName = $this->getProjectName(); @@ -133,16 +129,6 @@ private function shareDataWithShift(Project $project): void } } - private function renderMetricsAsciiTable($metrics): void - { - $this->info("\n"); - $this->info("The following metrics will be shared with stats.laravelshift.com."); - $this->table( - ['Name', 'Value'], - $metrics->toAsciiTableFormat() - ); - } - private function getProjectName(): ?string { if ($this->option('name')) { diff --git a/src/ShareableMetrics/MetricsCollection.php b/src/ShareableMetrics/MetricsCollection.php index 56eaa78a..3adae10b 100644 --- a/src/ShareableMetrics/MetricsCollection.php +++ b/src/ShareableMetrics/MetricsCollection.php @@ -6,33 +6,6 @@ class MetricsCollection extends Collection { - public function toAsciiTableFormat(): array - { - $projectMetrics = $this->items['project_metrics'] - ->map(function ($metric) { - if (is_array($metric)) { - return json_encode($metric, JSON_PRETTY_PRINT); - } - - if ($metric === true) { - return 'true'; - } - - if ($metric === false) { - return 'false'; - } - - return $metric; - }) - ->sort(); - - return $projectMetrics - ->forget('packages') - ->keys() - ->zip($projectMetrics) - ->toArray(); - } - public function toHttpPayload(string $projectName): array { $projectMetrics = $this->get('project_metrics'); From f5c2106ad2cf01103c1f4ddcfd0a545e205672f8 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 20:08:12 +0200 Subject: [PATCH 078/103] Add --payload option --- src/Console/StatsListCommand.php | 26 +++++++++++---------- src/ShareableMetrics/SendToLaravelShift.php | 8 +++++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 1fc27bfd..34e26c14 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -24,9 +24,9 @@ class StatsListCommand extends Command protected $signature = 'stats {--json : Output the statistics as JSON} {-c|--components= : Comma separated list of components which should be displayed} - {--s|share : Share project statistic with Laravel community } - {--no-send : Do not send the project statistic to Shift} - {--name= : The name used when sharing project statistics}'; + {--s|share : Share project statistic with Laravel community } + {--payload : Output payload to be shared with Laravel community } + {--name= : Name used when sharing project statistic}'; /** * The console command description. @@ -89,10 +89,10 @@ private function renderOutput(Project $project) $this->getArrayOfComponentsToDisplay() ); - if ($this->option('share') !== true) { + if ($this->option('payload') !== true) { $this->output->text(json_encode($json)); } - } else { + } elseif ($this->option('payload') !== true) { (new AsciiTableOutput($this->output))->render( $project, $this->option('verbose'), @@ -113,19 +113,21 @@ private function shareDataWithShift(Project $project): void return; } - if ($this->option('json') === false) { - $this->info("The project name '{$projectName}' will be used."); - } - - $payload = $metrics->toHttpPayload($projectName); - if ($this->option('no-send')) { + if ($this->option('payload')) { $this->output->text(json_encode($payload)); return; } - app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); + $wasSuccessful = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); + + if ($wasSuccessful) { + $this->info("Thanks for sharing your project statistic with the community!"); + return; + } + + $this->error("Unable to share stats. (Check logs for details)"); } } diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index a135b111..e75def04 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -7,7 +7,7 @@ class SendToLaravelShift { - public function send(array $payload): void + public function send(array $payload): bool { info('Sharing stats with stats.laravelshift.com', $payload); @@ -22,11 +22,15 @@ public function send(array $payload): void 'json' => $payload, ]); } catch (GuzzleException $exception) { - error('unable to share stats: ' . $exception->getMessage()); + info('Unable to share stats: ' . $exception->getMessage()); + return false; } if (in_array($response->getStatusCode(), [201, 204])) { info("Thanks for sharing your project data with the community!"); + return true; } + + return false; } } From 0043976b937a4f247d3dd33c253498bf31121ff3 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 20:30:07 +0200 Subject: [PATCH 079/103] Replace phploc/phploc with registered fork --- composer.json | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/composer.json b/composer.json index 126a3742..cd523947 100644 --- a/composer.json +++ b/composer.json @@ -17,7 +17,7 @@ "ext-json": "*", "illuminate/console": "^6.0 || ^7.0", "illuminate/support": "^6.0 || ^7.0", - "phploc/phploc": "dev-metrics", + "stefanzweifel/laravel-stats-phploc": "^6.1", "symfony/finder": "^4.3 || ^5.0", "symfony/process": "^4.3 || ^5.0" }, @@ -55,9 +55,5 @@ "Wnx\\LaravelStats\\StatsServiceProvider" ] } - }, - "repositories": [{ - "type": "vcs", - "url": "git@github.com:stefanzweifel/phploc.git" - }] + } } From 66991446c9caf8f717cbe73e2c7dc9e09a6e586a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 20:33:17 +0200 Subject: [PATCH 080/103] Run tests also against Laravel 6.* --- .github/workflows/tests.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b2a13f6e..e8433537 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,9 +10,11 @@ jobs: fail-fast: true matrix: php: [7.3, 7.4] - laravel: [7.*] + laravel: [6.*, 7.*] dependency-version: [prefer-lowest, prefer-stable] include: + - laravel: 6.* + testbench: 4.* - laravel: 7.* testbench: 5.* From 70ea91e0c5e688cfd453642480cbdfe57fac599c Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 20:38:31 +0200 Subject: [PATCH 081/103] Revert "Run tests also against Laravel 6.*" This reverts commit 66991446c9caf8f717cbe73e2c7dc9e09a6e586a. --- .github/workflows/tests.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index e8433537..b2a13f6e 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,11 +10,9 @@ jobs: fail-fast: true matrix: php: [7.3, 7.4] - laravel: [6.*, 7.*] + laravel: [7.*] dependency-version: [prefer-lowest, prefer-stable] include: - - laravel: 6.* - testbench: 4.* - laravel: 7.* testbench: 5.* From 72143a26e2c66ed81a350c9314dad6cd71bb5046 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 20:49:07 +0200 Subject: [PATCH 082/103] Make request to Shift with --payload option --- src/Console/StatsListCommand.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index 34e26c14..de679d8d 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -117,11 +117,14 @@ private function shareDataWithShift(Project $project): void if ($this->option('payload')) { $this->output->text(json_encode($payload)); - return; } $wasSuccessful = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); + if ($this->option('payload')) { + return; + } + if ($wasSuccessful) { $this->info("Thanks for sharing your project statistic with the community!"); return; From e400b37151016681ba02c98bdb8c304dd1b8626a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 15 Jul 2020 20:53:01 +0200 Subject: [PATCH 083/103] Update README --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 4240aaef..be62209e 100644 --- a/README.md +++ b/README.md @@ -225,6 +225,33 @@ class RepositoryClassifier implements Classifier ... ``` +## Share Metrics with the Laravel Community +> TODO: Intro to what --share does and where to find charts + + +You can share your projects statistic by using the `--share` option. + +```shell +php artisan stats --share +``` + +### Share statistic through CI + +If you would like to share your project statistic in an environment where you don't have access to a running shell, you can use the `--no-interaction` and `--name`-options. + +Use the following command in your CI script to share your project statistic automatically. Update `org/repo` with the name of your application (eg. `stefanzweifel/`). + +```shell +php artisan stats --share --no-interaction --name=org/repo +``` + +If you're using GitHub Actions you can use the following Workflow template to share data once a week. +> TODO: Add GitHub Actions link here. + +### See Request Data shared with the community + +> TODO: Describe how to use the `--dry-option`. + ## Treeware You're free to use this package, but if it makes it to your production environment you are required to buy the world a tree. From bb0c29eff18b416af73ab9aa0db0d0c59b0ba3b7 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 21 Jul 2020 21:02:17 +0200 Subject: [PATCH 084/103] Add --dry-run option --- src/Console/StatsListCommand.php | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index de679d8d..bd58c201 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -25,8 +25,9 @@ class StatsListCommand extends Command {--json : Output the statistics as JSON} {-c|--components= : Comma separated list of components which should be displayed} {--s|share : Share project statistic with Laravel community } + {--name= : Name used when sharing project statistic} {--payload : Output payload to be shared with Laravel community } - {--name= : Name used when sharing project statistic}'; + {--dry-run : Do not make request to share statistic}'; /** * The console command description. @@ -119,6 +120,10 @@ private function shareDataWithShift(Project $project): void $this->output->text(json_encode($payload)); } + if ($this->option('dry-run')) { + return; + } + $wasSuccessful = app(SendToLaravelShift::class)->send($metrics->toHttpPayload($projectName)); if ($this->option('payload')) { From 1c81c5e002f1ce7d1ac13674b79d30b5b92fe4bf Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 21 Jul 2020 21:02:30 +0200 Subject: [PATCH 085/103] Remove ".git" from project names --- src/ShareableMetrics/ProjectName.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ShareableMetrics/ProjectName.php b/src/ShareableMetrics/ProjectName.php index d50c903b..fa271fef 100644 --- a/src/ShareableMetrics/ProjectName.php +++ b/src/ShareableMetrics/ProjectName.php @@ -30,7 +30,9 @@ public function determineProjectNameFromGit(): ?string $remoteUrl = parse_url(trim($process->getOutput())); - return Str::replaceFirst('/', '', $remoteUrl['path']); + $remoteUrl = Str::replaceLast('.git', '', $remoteUrl['path']); + + return Str::replaceFirst('/', '', $remoteUrl); } protected function pathToRcFile(): string From 910a03f80cd8d6220a86cff1e8d32f74d9a18636 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 21 Jul 2020 21:02:53 +0200 Subject: [PATCH 086/103] Don't make Http Request in Test Suite --- src/ShareableMetrics/SendToLaravelShift.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index e75def04..a3ee424f 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -11,6 +11,10 @@ public function send(array $payload): bool { info('Sharing stats with stats.laravelshift.com', $payload); + if (app()->environment('testing')) { + return true; + } + try { $client = new Client([ 'base_uri' => 'https://laravelshift.com', From 8b9408177b5a0e7efb8e0100df5175685b6f8e79 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 21 Jul 2020 21:03:05 +0200 Subject: [PATCH 087/103] Add Tests --- tests/Console/StatsListCommandTest.php | 64 ++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/tests/Console/StatsListCommandTest.php b/tests/Console/StatsListCommandTest.php index 52eead06..f3414f26 100644 --- a/tests/Console/StatsListCommandTest.php +++ b/tests/Console/StatsListCommandTest.php @@ -120,4 +120,68 @@ public function it_only_returns_stats_for_given_components() $this->assertStringContainsString('StatsListCommand', $output); $this->assertStringNotContainsString('StatsListCommandTest', $output); } + + /** @test */ + public function it_allows_users_to_share_project_statistics_with_the_community() + { + $this->artisan('stats', [ + '--share' => true, + '--no-interaction' => true, + ]); + $output = Artisan::output(); + + $this->assertStringContainsString('Thanks for sharing your project statistic with the community!', $output); + } + + /** @test */ + public function it_does_not_show_success_message_for_share_option_if_dry_run_option_is_passed() + { + $this->artisan('stats', [ + '--share' => true, + '--no-interaction' => true, + '--dry-run' => true, + ]); + $output = Artisan::output(); + + $this->assertStringNotContainsString('Thanks for sharing your project statistic with the community!', $output); + } + + /** @test */ + public function it_output_payload_to_be_sent_to_shift() + { + $this->artisan('stats', [ + '--share' => true, + '--no-interaction' => true, + '--payload' => true, + ]); + $output = Artisan::output(); + + $output = json_decode(trim($output), true); + + $this->assertIsArray($output); + $this->assertArrayHasKey('project', $output); + $this->assertArrayHasKey('metrics', $output); + + $this->assertEquals('stefanzweifel/laravel-stats', $output['project']); + } + + /** @test */ + public function it_allows_users_to_set_project_name_through_command_option() + { + $this->artisan('stats', [ + '--share' => true, + '--no-interaction' => true, + '--payload' => true, + '--name' => 'repo/org' + ]); + $output = Artisan::output(); + + $output = json_decode(trim($output), true); + + $this->assertIsArray($output); + $this->assertArrayHasKey('project', $output); + $this->assertArrayHasKey('metrics', $output); + + $this->assertEquals('repo/org', $output['project']); + } } From c2af2131afb8adc7aad6630f86856aa19641791e Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Tue, 21 Jul 2020 21:10:09 +0200 Subject: [PATCH 088/103] Fix Tests --- tests/Console/StatsListCommandTest.php | 23 +++-------------------- 1 file changed, 3 insertions(+), 20 deletions(-) diff --git a/tests/Console/StatsListCommandTest.php b/tests/Console/StatsListCommandTest.php index f3414f26..115f3037 100644 --- a/tests/Console/StatsListCommandTest.php +++ b/tests/Console/StatsListCommandTest.php @@ -127,6 +127,7 @@ public function it_allows_users_to_share_project_statistics_with_the_community() $this->artisan('stats', [ '--share' => true, '--no-interaction' => true, + '--name' => 'repo/org', ]); $output = Artisan::output(); @@ -140,6 +141,7 @@ public function it_does_not_show_success_message_for_share_option_if_dry_run_opt '--share' => true, '--no-interaction' => true, '--dry-run' => true, + '--name' => 'repo/org', ]); $output = Artisan::output(); @@ -153,26 +155,7 @@ public function it_output_payload_to_be_sent_to_shift() '--share' => true, '--no-interaction' => true, '--payload' => true, - ]); - $output = Artisan::output(); - - $output = json_decode(trim($output), true); - - $this->assertIsArray($output); - $this->assertArrayHasKey('project', $output); - $this->assertArrayHasKey('metrics', $output); - - $this->assertEquals('stefanzweifel/laravel-stats', $output['project']); - } - - /** @test */ - public function it_allows_users_to_set_project_name_through_command_option() - { - $this->artisan('stats', [ - '--share' => true, - '--no-interaction' => true, - '--payload' => true, - '--name' => 'repo/org' + '--name' => 'repo/org', ]); $output = Artisan::output(); From 38c6ae817199c461ae6241645236e0c3072ccf0a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 29 Jul 2020 17:15:34 +0200 Subject: [PATCH 089/103] Update dependency constraints to work under Laravel 6 --- .github/workflows/tests.yml | 4 +++- composer.json | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index b2a13f6e..e8433537 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,9 +10,11 @@ jobs: fail-fast: true matrix: php: [7.3, 7.4] - laravel: [7.*] + laravel: [6.*, 7.*] dependency-version: [prefer-lowest, prefer-stable] include: + - laravel: 6.* + testbench: 4.* - laravel: 7.* testbench: 5.* diff --git a/composer.json b/composer.json index cd523947..84cf1d3b 100644 --- a/composer.json +++ b/composer.json @@ -23,11 +23,11 @@ }, "require-dev": { "friendsofphp/php-cs-fixer": "^2.15", - "laravel/browser-kit-testing": "~6.0", + "laravel/browser-kit-testing": "~5.0 || ~6.0", "laravel/dusk": "~5.0", "mockery/mockery": "^1.1", - "orchestra/testbench": "^5.0", - "phpunit/phpunit": "9.*", + "orchestra/testbench": "^4.0 || ^5.0", + "phpunit/phpunit": "8.* || 9.*", "psalm/plugin-laravel": "^1.3", "vimeo/psalm": "^3.12" }, From 97a461ea75679bb4a639250e5270454b7fd78d15 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 29 Jul 2020 17:38:38 +0200 Subject: [PATCH 090/103] Make Tests Compatible with Laravel 6 --- src/Classifiers/BladeComponentClassifier.php | 4 ++++ src/Classifiers/CustomCastClassifier.php | 5 +++++ tests/ClassesFinderTest.php | 14 +++++++++++--- tests/Classifiers/BladeComponentClassifierTest.php | 4 ++++ tests/Classifiers/CustomCastClassifierTest.php | 8 ++++++++ tests/TestCase.php | 10 ++++++++++ 6 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/Classifiers/BladeComponentClassifier.php b/src/Classifiers/BladeComponentClassifier.php index a81b39ac..03bf39f7 100644 --- a/src/Classifiers/BladeComponentClassifier.php +++ b/src/Classifiers/BladeComponentClassifier.php @@ -15,6 +15,10 @@ public function name(): string public function satisfies(ReflectionClass $class): bool { + if (! class_exists(Component::class)) { + return false; + } + return $class->isSubclassOf(Component::class); } diff --git a/src/Classifiers/CustomCastClassifier.php b/src/Classifiers/CustomCastClassifier.php index 21e71da7..cd0ce205 100644 --- a/src/Classifiers/CustomCastClassifier.php +++ b/src/Classifiers/CustomCastClassifier.php @@ -4,6 +4,7 @@ use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes; +use Illuminate\Contracts\Validation\Rule; use Wnx\LaravelStats\Contracts\Classifier; use Wnx\LaravelStats\ReflectionClass; @@ -16,6 +17,10 @@ public function name(): string public function satisfies(ReflectionClass $class): bool { + if ((float) app()->version() < 7) { + return false; + } + return $class->implementsInterface(CastsAttributes::class) || $class->implementsInterface(CastsInboundAttributes::class); } diff --git a/tests/ClassesFinderTest.php b/tests/ClassesFinderTest.php index d8ee8289..997be6b1 100644 --- a/tests/ClassesFinderTest.php +++ b/tests/ClassesFinderTest.php @@ -10,13 +10,21 @@ public function setUp() : void { parent::setUp(); + $excludedFiles = [ + __DIR__.'/../tests/Stubs/ExcludedFile.php', + ]; + + if ($this->getLaravelVersion() < 7) { + $excludedFiles[] = __DIR__.'/../tests/Stubs/CustomCasts/StubCast.php'; + $excludedFiles[] = __DIR__.'/../tests/Stubs/CustomCasts/StubInboundCast.php'; + $excludedFiles[] = __DIR__.'/../tests/Stubs/BladeComponents/StubBladeComponent.php'; + } + config()->set('stats', [ 'paths' => [ __DIR__.'/../tests/Stubs', ], - 'exclude' => [ - __DIR__.'/../tests/Stubs/ExcludedFile.php', - ], + 'exclude' => $excludedFiles, 'ignored_namespaces' => [], ]); diff --git a/tests/Classifiers/BladeComponentClassifierTest.php b/tests/Classifiers/BladeComponentClassifierTest.php index df7fb153..cd9b8242 100644 --- a/tests/Classifiers/BladeComponentClassifierTest.php +++ b/tests/Classifiers/BladeComponentClassifierTest.php @@ -12,6 +12,10 @@ class BladeComponentClassifierTest extends TestCase /** @test */ public function it_returns_true_if_given_class_is_a_blade_component() { + if ($this->getLaravelVersion() < 7) { + $this->markTestSkipped("Can't run test on older Laravel Versions"); + } + $this->assertTrue( (new BladeComponentClassifier())->satisfies( new ReflectionClass(StubBladeComponent::class) diff --git a/tests/Classifiers/CustomCastClassifierTest.php b/tests/Classifiers/CustomCastClassifierTest.php index 299e099b..76772b04 100644 --- a/tests/Classifiers/CustomCastClassifierTest.php +++ b/tests/Classifiers/CustomCastClassifierTest.php @@ -13,6 +13,10 @@ class CustomCastClassifierTest extends TestCase /** @test */ public function it_returns_true_if_given_class_is_a_custom_cast() { + if ($this->getLaravelVersion() < 7) { + $this->markTestSkipped("Can't run test on older Laravel Versions"); + } + $this->assertTrue( (new CustomCastClassifier())->satisfies( new ReflectionClass(StubCast::class) @@ -23,6 +27,10 @@ public function it_returns_true_if_given_class_is_a_custom_cast() /** @test */ public function it_returns_true_if_given_class_is_a_custom_inbound_cast() { + if ($this->getLaravelVersion() < 7) { + $this->markTestSkipped("Can't run test on older Laravel Versions"); + } + $this->assertTrue( (new CustomCastClassifier())->satisfies( new ReflectionClass(StubInboundCast::class) diff --git a/tests/TestCase.php b/tests/TestCase.php index 98e931f1..110fb76b 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -60,4 +60,14 @@ public function createProjectFromClasses(array $classes = []) return new Project($classes); } + + /** + * Get currently installed Laravel Version + * + * @return float + */ + public function getLaravelVersion(): float + { + return (float) app()->version(); + } } From 68a5a2b745078ba5f42c477e9a478f339f93e89a Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Wed, 29 Jul 2020 15:39:52 +0000 Subject: [PATCH 091/103] Apply php-cs-fixer changes --- src/Classifiers/CustomCastClassifier.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Classifiers/CustomCastClassifier.php b/src/Classifiers/CustomCastClassifier.php index cd0ce205..d421c27f 100644 --- a/src/Classifiers/CustomCastClassifier.php +++ b/src/Classifiers/CustomCastClassifier.php @@ -4,7 +4,6 @@ use Illuminate\Contracts\Database\Eloquent\CastsAttributes; use Illuminate\Contracts\Database\Eloquent\CastsInboundAttributes; -use Illuminate\Contracts\Validation\Rule; use Wnx\LaravelStats\Contracts\Classifier; use Wnx\LaravelStats\ReflectionClass; From 8dec7cb325aa598bdbb819584baab0de60b6879b Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 29 Jul 2020 20:09:50 +0200 Subject: [PATCH 092/103] Change default value for confirmation question --- src/Console/StatsListCommand.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index bd58c201..bd8219eb 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -106,7 +106,9 @@ private function shareDataWithShift(Project $project): void { $metrics = app(CollectMetrics::class)->collect($project); - if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", true)) { + $defaultValueForConfirmation = $this->option('no-interaction') ?? false; + + if ($this->confirm("Do you want to share stats above from your project with the Laravel Community to stats.laravelshift.com?", $defaultValueForConfirmation)) { $projectName = $this->getProjectName(); if ($projectName === null) { From e8e5a56a5edb927a85cd80b20be383936f49af3a Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Wed, 29 Jul 2020 20:10:02 +0200 Subject: [PATCH 093/103] Increment Timeout to Share API --- src/ShareableMetrics/SendToLaravelShift.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ShareableMetrics/SendToLaravelShift.php b/src/ShareableMetrics/SendToLaravelShift.php index a3ee424f..87873907 100644 --- a/src/ShareableMetrics/SendToLaravelShift.php +++ b/src/ShareableMetrics/SendToLaravelShift.php @@ -18,7 +18,7 @@ public function send(array $payload): bool try { $client = new Client([ 'base_uri' => 'https://laravelshift.com', - 'timeout' => 1, + 'timeout' => 5, 'headers' => ['Accept' => 'application/json'], ]); From 826a478c08d5213d2fd041ec8f876158c31bcbd9 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 3 Aug 2020 13:57:05 +0200 Subject: [PATCH 094/103] Update Typo in config/stats.php --- config/stats.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/stats.php b/config/stats.php index 66f5b5d2..04bca7a6 100644 --- a/config/stats.php +++ b/config/stats.php @@ -44,7 +44,7 @@ /* * Namespaces which should be ignored. - * Laravel Stats uses the `Str::startsWith()`class to + * Laravel Stats uses the `Str::startsWith()` helper to * check if a Namespace should be ignored. * * You can use `Illuminate` to ignore the entire `Illuminate`-namespace From cd2ea27a590d7bea44bf7e26ccde1f879e497ca3 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 3 Aug 2020 13:57:12 +0200 Subject: [PATCH 095/103] Update README --- README.md | 128 ++++++++++++++++++++---------------------------------- 1 file changed, 47 insertions(+), 81 deletions(-) diff --git a/README.md b/README.md index be62209e..863bbd4c 100644 --- a/README.md +++ b/README.md @@ -26,9 +26,7 @@ ### Installing -The easiest way to install the package is by using composer. The package requires PHP 7.3, Laravel 7.0 or higher or Lumen 7.0 or higher. - -Due to version conflicts, `stats` can't be installed in Laravel 7 projects which are running with phpunit 8. **Phpunit 9 is required.** +The easiest way to install the package is by using composer. The package requires PHP 7.3, Laravel 6.0 or higher or Lumen 6.0 or higher. ```shell composer require "wnx/laravel-stats" --dev @@ -42,78 +40,12 @@ If you're using Lumen you have to manually register the Service Provider in your $app->register(\Wnx\LaravelStats\StatsServiceProvider::class); ``` -Optionally, you can publish the config file of this package with this command (Laravel only): +Optionally, you can publish the config file in your Laravel applications with the following command: ```shell php artisan vendor:publish --provider="Wnx\LaravelStats\StatsServiceProvider" ``` -The following config file will be published in `config/stats.php` - -```php - [ - base_path('app'), - base_path('database'), - base_path('tests'), - ], - - /* - * List of files/folders to be excluded from analysis. - */ - 'exclude' => [ - // base_path('app/helpers.php'), - // base_path('app/Services'), - ], - - /* - * List of your custom Classifiers - */ - 'custom_component_classifier' => [ - // \App\Classifiers\CustomerExportClassifier::class - ], - - /* - * The Strategy used to reject Classes from the project statistics. - * - * By default all Classes located in - * the vendor directory are being rejected and don't - * count to the statistics. - * - * The package ships with 2 strategies: - * - \Wnx\LaravelStats\RejectionStrategies\RejectVendorClasses::class - * - \Wnx\LaravelStats\RejectionStrategies\RejectInternalClasses::class - * - * If none of the default strategies fit for your usecase, you can - * write your own class which implements the RejectionStrategy Contract. - */ - 'rejection_strategy' => \Wnx\LaravelStats\RejectionStrategies\RejectVendorClasses::class, - - /* - * Namespaces which should be ignored. - * Laravel Stats uses the `Str::startsWith()`class to - * check if a Namespace should be ignored. - * - * You can use `Illuminate` to ignore the entire `Illuminate`-namespace - * or `Illuminate\Support` to ignore a subset of the namespace. - */ - 'ignored_namespaces' => [ - 'Wnx\LaravelStats', - 'Illuminate', - 'Symfony', - ], - -]; - -``` - - ## Usage After installing you can generate the statistics by running the following Artisan Command. @@ -134,14 +66,13 @@ If you want a more detailed report and see which classes have been grouped into php artisan stats --verbose ``` -The verbose option is also available for the JSON format. +The verbose option is available for the JSON format also. ``` php artisan stats --json --verbose ``` - ## How does this package detect certain Laravel Components? The package scans the files defined in the `paths`-array in the configuration file. It then applies [Classifiers](https://github.com/stefanzweifel/laravel-stats/tree/master/src/Classifiers) to those classes to determine which Laravel Component the class represents. @@ -226,31 +157,66 @@ class RepositoryClassifier implements Classifier ``` ## Share Metrics with the Laravel Community -> TODO: Intro to what --share does and where to find charts - -You can share your projects statistic by using the `--share` option. +You can optionally share your projects statistic by using the `--share` option. ```shell php artisan stats --share ``` +Your project statistics is shared anonymously with [stats.laravelshift.com](https://stats.laravelshift.com). In regular intervals the dashboard and charts on the site are updated with shared data from other Laravel projects. + +To learn more about this feature, please check out PR [#178](https://github.com/stefanzweifel/laravel-stats/pull/178). + ### Share statistic through CI -If you would like to share your project statistic in an environment where you don't have access to a running shell, you can use the `--no-interaction` and `--name`-options. +If you would like to share your project statistic in a CI environment you can use the `--no-interaction` and `--name`-options. -Use the following command in your CI script to share your project statistic automatically. Update `org/repo` with the name of your application (eg. `stefanzweifel/`). +Use the following command in your CI script to share your project statistic automatically. (Update `org/repo` with the name of your application (eg. `acme/podcasting-app`)) ```shell php artisan stats --share --no-interaction --name=org/repo ``` -If you're using GitHub Actions you can use the following Workflow template to share data once a week. -> TODO: Add GitHub Actions link here. +If you're code is hosted on GitHub, you can integrate `stats` with [GitHub Actions](https://docs.github.com/en/actions). +Use the following Workflow template to share data when a commit is pushed to the `master` branch. The Action automatically uses your GitHub repository name. + +```yaml +name: stats + +on: + push: + branches: + - master + +jobs: + stats: + runs-on: ubuntu-latest -### See Request Data shared with the community + steps: + - name: Checkout code + uses: actions/checkout@v2 -> TODO: Describe how to use the `--dry-option`. + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: 7.4 + tools: composer:v2 + + - name: Install dependencies + run: composer install --prefer-dist --no-interaction --no-suggest + + - name: Share Stats + run: php artisan stats --share --name=$GITHUB_REPOSITORY --no-interaction +``` + +### Inspect Data shared with the Community + +If you would like to inspect the payload the command is sending to the API you can use the `--dry-run` and `--payload` options. + +```shell +php artisan stats --share --dry-run --payload --name="org/repo" --no-interaction +``` ## Treeware From d2212814e27cc8cecb8a8a9ba8f50ebfa86cdb17 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Thu, 6 Aug 2020 17:58:14 +0200 Subject: [PATCH 096/103] Add ProjectLogicalLinesOfCodePerMethod --- src/ShareableMetrics/CollectMetrics.php | 4 +++- .../ProjectLogicalLinesOfCodePerMethod.php | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodePerMethod.php diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index 8253e1e2..f38fde1b 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -15,10 +15,11 @@ use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsFolder; use Wnx\LaravelStats\ShareableMetrics\Metrics\ModelsMassAssignment; use Wnx\LaravelStats\ShareableMetrics\Metrics\NumberOfRoutes; -use Wnx\LaravelStats\ShareableMetrics\Metrics\ScheduledTasks; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLinesOfCode; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLogicalLinesOfCode; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectLogicalLinesOfCodePerMethod; use Wnx\LaravelStats\ShareableMetrics\Metrics\ProjectNumberOfClasses; +use Wnx\LaravelStats\ShareableMetrics\Metrics\ScheduledTasks; use Wnx\LaravelStats\ValueObjects\Component; class CollectMetrics @@ -45,6 +46,7 @@ protected function getProjectMetrics(Project $project): Collection NumberOfRoutes::class, ProjectLinesOfCode::class, ProjectLogicalLinesOfCode::class, + ProjectLogicalLinesOfCodePerMethod::class, ProjectNumberOfClasses::class, ScheduledTasks::class, ])->map(function ($statClass) use ($project) { diff --git a/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodePerMethod.php b/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodePerMethod.php new file mode 100644 index 00000000..acc32d32 --- /dev/null +++ b/src/ShareableMetrics/Metrics/ProjectLogicalLinesOfCodePerMethod.php @@ -0,0 +1,18 @@ +project->statistic()->getLogicalLinesOfCodePerMethod(); + } +} From 7595d3979b7aa44e78ecd9fa5446f0bfda0dbe55 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 10 Aug 2020 07:34:24 +0200 Subject: [PATCH 097/103] Add validation for project name --- src/Console/StatsListCommand.php | 5 +++++ tests/Console/StatsListCommandTest.php | 13 +++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index bd8219eb..a4ffaeaf 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -116,6 +116,11 @@ private function shareDataWithShift(Project $project): void return; } + if (! Str::contains($projectName, '/')) { + $this->error("Please use the organisation/repository schema for naming your project."); + return; + } + $payload = $metrics->toHttpPayload($projectName); if ($this->option('payload')) { diff --git a/tests/Console/StatsListCommandTest.php b/tests/Console/StatsListCommandTest.php index 115f3037..7e80a55f 100644 --- a/tests/Console/StatsListCommandTest.php +++ b/tests/Console/StatsListCommandTest.php @@ -134,6 +134,19 @@ public function it_allows_users_to_share_project_statistics_with_the_community() $this->assertStringContainsString('Thanks for sharing your project statistic with the community!', $output); } + /** @test */ + public function it_shows_error_message_when_project_name_does_not_follow_org_repo_schema_when_sharing() + { + $this->artisan('stats', [ + '--share' => true, + '--no-interaction' => true, + '--name' => 'foo', + ]); + $output = Artisan::output(); + + $this->assertStringContainsString('Please use the organisation/repository schema for naming your project.', $output); + } + /** @test */ public function it_does_not_show_success_message_for_share_option_if_dry_run_option_is_passed() { From a37f73b2a48bd27929017bb4aa1f9514588e27f6 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 10 Aug 2020 19:11:08 +0200 Subject: [PATCH 098/103] Update GitHub Actions part in README --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 863bbd4c..dbe061f5 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ php artisan stats --share --no-interaction --name=org/repo ``` If you're code is hosted on GitHub, you can integrate `stats` with [GitHub Actions](https://docs.github.com/en/actions). -Use the following Workflow template to share data when a commit is pushed to the `master` branch. The Action automatically uses your GitHub repository name. +Copy the following Workflow to `.github/workflows/laravel-stats.yml`. It will share data when a commit is pushed to the `master` branch. The Action automatically uses your GitHub repository name in the `--name`-option. ```yaml name: stats @@ -215,7 +215,7 @@ jobs: If you would like to inspect the payload the command is sending to the API you can use the `--dry-run` and `--payload` options. ```shell -php artisan stats --share --dry-run --payload --name="org/repo" --no-interaction +php artisan stats --share --no-interaction --name="org/repo" --dry-run --payload ``` ## Treeware From 96e6322280d0c48603a8ccb60e6e2fb49c95f8b4 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 10 Aug 2020 19:17:52 +0200 Subject: [PATCH 099/103] Improve wording when asking for project name --- src/Console/StatsListCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Console/StatsListCommand.php b/src/Console/StatsListCommand.php index a4ffaeaf..fd31659f 100644 --- a/src/Console/StatsListCommand.php +++ b/src/Console/StatsListCommand.php @@ -155,7 +155,7 @@ private function getProjectName(): ?string if (app(ProjectName::class)->hasStoredProjectName() === false) { $generatedProjectName = app(ProjectName::class)->determineProjectNameFromGit(); - $projectName = $this->ask("We've determined the following name for your project. Do you want to rename it?", $generatedProjectName); + $projectName = $this->ask("We've determined the following name for your project: \"{$generatedProjectName}\".\n Type a new name or leave it blank to continue.", $generatedProjectName); app(ProjectName::class)->storeNameInRcFile($projectName); From d4aed4416cbbe5e8f8455782c1a864cc16c9208e Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 24 Aug 2020 20:15:41 +0200 Subject: [PATCH 100/103] Determine git binary path in ProjectName --- src/ShareableMetrics/ProjectName.php | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ShareableMetrics/ProjectName.php b/src/ShareableMetrics/ProjectName.php index fa271fef..8ad6087f 100644 --- a/src/ShareableMetrics/ProjectName.php +++ b/src/ShareableMetrics/ProjectName.php @@ -21,7 +21,13 @@ public function get(): ?string public function determineProjectNameFromGit(): ?string { - $process = Process::fromShellCommandline('/usr/local/bin/git config --get remote.origin.url'); + $gitPath = $this->getGitBinaryPath(); + + if (is_null($gitPath)) { + return null; + } + + $process = Process::fromShellCommandline("{$gitPath} config --get remote.origin.url"); $process->run(); if ($process->isSuccessful() === false) { @@ -35,6 +41,18 @@ public function determineProjectNameFromGit(): ?string return Str::replaceFirst('/', '', $remoteUrl); } + protected function getGitBinaryPath(): ?string + { + $process = Process::fromShellCommandline('which git'); + $process->run(); + + if ($process->isSuccessful() === false) { + return null; + } + + return trim($process->getOutput()); + } + protected function pathToRcFile(): string { return base_path(self::RC_FILE); From 2c8a8de1ea66a34eaced593542504ed13e29eaa1 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 24 Aug 2020 20:34:06 +0200 Subject: [PATCH 101/103] Add PROJECT_METRICS Constant --- src/ShareableMetrics/CollectMetrics.php | 44 ++++++++++++++----------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/src/ShareableMetrics/CollectMetrics.php b/src/ShareableMetrics/CollectMetrics.php index f38fde1b..8ff166d7 100644 --- a/src/ShareableMetrics/CollectMetrics.php +++ b/src/ShareableMetrics/CollectMetrics.php @@ -24,6 +24,23 @@ class CollectMetrics { + public const PROJECT_METRICS = [ + CodeTestRatio::class, + ComposerPsr4Sources::class, + ControllersCustomInheritance::class, + ControllersFormRequestInjection::class, + InstalledPackages::class, + ModelsCustomInheritance::class, + ModelsFolder::class, + ModelsMassAssignment::class, + NumberOfRoutes::class, + ProjectLinesOfCode::class, + ProjectLogicalLinesOfCode::class, + ProjectLogicalLinesOfCodePerMethod::class, + ProjectNumberOfClasses::class, + ScheduledTasks::class, + ]; + public function collect(Project $project): MetricsCollection { return new MetricsCollection([ @@ -34,26 +51,13 @@ public function collect(Project $project): MetricsCollection protected function getProjectMetrics(Project $project): Collection { - $availableMetrics = collect([ - CodeTestRatio::class, - ComposerPsr4Sources::class, - ControllersCustomInheritance::class, - ControllersFormRequestInjection::class, - InstalledPackages::class, - ModelsCustomInheritance::class, - ModelsFolder::class, - ModelsMassAssignment::class, - NumberOfRoutes::class, - ProjectLinesOfCode::class, - ProjectLogicalLinesOfCode::class, - ProjectLogicalLinesOfCodePerMethod::class, - ProjectNumberOfClasses::class, - ScheduledTasks::class, - ])->map(function ($statClass) use ($project) { - return new $statClass($project); - }); - - return $availableMetrics->map->toArray()->collapse(); + return collect(self::PROJECT_METRICS) + ->map(function ($metricClass) use ($project) { + return new $metricClass($project); + }) + ->map + ->toArray() + ->collapse(); } protected function getComponentMetrics(Project $project): Collection From 3eebc7329300cb8dae028d19498e4fa8f9c2a0e0 Mon Sep 17 00:00:00 2001 From: Stefan Zweifel Date: Mon, 24 Aug 2020 20:34:36 +0200 Subject: [PATCH 102/103] Add AllMetricPayloadKeys This Class is mostly used for internal development purposes. --- src/ShareableMetrics/AllMetricPayloadKeys.php | 54 +++++++++++++++++++ .../AllMetricPayloadKeysTest.php | 23 ++++++++ 2 files changed, 77 insertions(+) create mode 100644 src/ShareableMetrics/AllMetricPayloadKeys.php create mode 100644 tests/ShareableMetrics/AllMetricPayloadKeysTest.php diff --git a/src/ShareableMetrics/AllMetricPayloadKeys.php b/src/ShareableMetrics/AllMetricPayloadKeys.php new file mode 100644 index 00000000..0201c855 --- /dev/null +++ b/src/ShareableMetrics/AllMetricPayloadKeys.php @@ -0,0 +1,54 @@ +getProjectMetricKeys() + ->merge($this->getComponentMetricKeys()) + ->toArray(); + } + + private function getProjectMetricKeys(): Collection + { + return collect(CollectMetrics::PROJECT_METRICS) + ->map(function ($metricClass) { + return new $metricClass(new Project(collect([]))); + }) + ->map(function ($metric) { + return $metric->name(); + }); + } + + private function getComponentMetricKeys(): Collection + { + $coreClassifierNames = array_map(function ($classifier) { + return (new $classifier)->name(); + }, Classifier::DEFAULT_CLASSIFIER); + + $metrics = []; + + /** @var Component $component */ + foreach ($coreClassifierNames as $coreClassifier) { + $slug = Str::slug(strtolower($coreClassifier), '_'); + + $metrics[] = [ + "{$slug}", + "{$slug}_methods", + "{$slug}_loc", + "{$slug}_lloc", + "{$slug}_lloc_per_method", + ]; + } + + return collect($metrics)->flatten(); + } +} diff --git a/tests/ShareableMetrics/AllMetricPayloadKeysTest.php b/tests/ShareableMetrics/AllMetricPayloadKeysTest.php new file mode 100644 index 00000000..57ce002d --- /dev/null +++ b/tests/ShareableMetrics/AllMetricPayloadKeysTest.php @@ -0,0 +1,23 @@ +get(); + + $this->assertIsArray($result); + + $this->assertContains('packages', $result); + $this->assertContains('routes', $result); + $this->assertContains('models_mass_assignment', $result); + $this->assertContains('controllers_lloc_per_method', $result); + $this->assertContains('nova_lenses_methods', $result); + } +} From 952540f3403d1b444ba023071f7764018c91b964 Mon Sep 17 00:00:00 2001 From: stefanzweifel Date: Tue, 1 Sep 2020 17:51:45 +0000 Subject: [PATCH 103/103] Apply php-cs-fixer changes --- src/ShareableMetrics/AllMetricPayloadKeys.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ShareableMetrics/AllMetricPayloadKeys.php b/src/ShareableMetrics/AllMetricPayloadKeys.php index 0201c855..5ee72d25 100644 --- a/src/ShareableMetrics/AllMetricPayloadKeys.php +++ b/src/ShareableMetrics/AllMetricPayloadKeys.php @@ -1,4 +1,4 @@ -