├── .editorconfig
├── .gitattributes
├── .gitignore
├── README.md
├── app
├── Application
│ ├── .gitkeep
│ ├── Load
│ │ ├── LoadHandler.php
│ │ ├── LoadOutputInterface.php
│ │ └── LoadRequestInterface.php
│ └── Report
│ │ ├── ReportHandler.php
│ │ ├── ReportOutputInterface.php
│ │ └── ReportRequestInterface.php
├── Domain
│ ├── .gitkeep
│ ├── Aggregators
│ │ ├── ReportAggregator.php
│ │ └── TrackedFileAggregator.php
│ ├── Contracts
│ │ ├── Gateways
│ │ │ └── FileVersionControlGateway.php
│ │ └── Repositories
│ │ │ └── TrackedFileRepository.php
│ ├── Entities
│ │ ├── Analysis.php
│ │ ├── Metric.php
│ │ ├── Path.php
│ │ ├── ReportLine.php
│ │ └── TrackedFile.php
│ └── Services
│ │ ├── ReportGenerator.php
│ │ ├── TrackedFileAnalyzer.php
│ │ └── TrackedFileService.php
├── Infrastructure
│ ├── .gitkeep
│ ├── Gateways
│ │ └── CliGitGateway.php
│ └── Repositories
│ │ └── TrackedFileStorageRepository.php
├── Presenter
│ └── Commands
│ │ ├── .gitkeep
│ │ ├── Load
│ │ ├── LoadCliOutput.php
│ │ ├── LoadCliRequest.php
│ │ └── LoadCommand.php
│ │ └── Report
│ │ ├── Cli
│ │ ├── Concerns
│ │ │ ├── Sorts.php
│ │ │ └── Thresholds.php
│ │ ├── ReportCliOutput.php
│ │ ├── ReportCliRequest.php
│ │ └── ReportClipOutputOptions.php
│ │ └── ReportCommand.php
└── Providers
│ └── AppServiceProvider.php
├── bootstrap
└── app.php
├── box.json
├── builds
└── php-git-insights-analyzer
├── composer.json
├── composer.lock
├── config
├── app.php
├── commands.php
└── filesystems.php
├── php-git-insights-analyzer
├── phpunit.xml.dist
└── tests
├── CreatesApplication.php
├── Feature
└── InspireCommandTest.php
├── Pest.php
├── TestCase.php
└── Unit
└── ExampleTest.php
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | end_of_line = lf
6 | insert_final_newline = true
7 | indent_style = space
8 | indent_size = 4
9 | trim_trailing_whitespace = true
10 |
11 | [*.md]
12 | trim_trailing_whitespace = false
13 |
14 | [*.yml]
15 | indent_size = 2
16 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto eol=lf
2 | /.github export-ignore
3 | .scrutinizer.yml export-ignore
4 | BACKERS.md export-ignore
5 | CONTRIBUTING.md export-ignore
6 | CHANGELOG.md export-ignore
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /vendor
2 | /.idea
3 | /.vscode
4 | /.vagrant
5 | .phpunit.result.cache
6 |
7 | storage/app/analyse.json
8 |
9 | analyse.json
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | # php-git-insights-analyzer
6 |
7 | ## Phar
8 | This tool is distributed as a [PHP Archive (PHAR)](https://www.php.net/phar):
9 |
10 | ```
11 | wget https://github.com/DeGraciaMathieu/php-git-insights-analyzer/raw/master/builds/php-git-insights-analyzer
12 | ```
13 |
14 | ```
15 | php php-git-insights-analyzer --version
16 | ```
17 |
18 | ## Usage
19 |
20 | First, you need to load the data required for the analysis :
21 |
22 | ```
23 | php php-git-insights-analyzer app:load
24 | ```
25 |
26 | Package uses git commands to retrieve files history, which is relatively time-consuming, so it was more efficient to create a database before carrying out the analyses.
27 |
28 | > For information, database is stored in the analyse.json
29 |
30 | Then analyse the data using the following command :
31 |
32 | ```
33 | php php-git-insights-analyzer app:report
34 | ```
35 |
36 | ```
37 | $ php php-git-insights-analyzer app:report
38 |
39 | ❀ PHP Git Insights Analyzer ❀
40 |
41 | ┌─────────────────────────────────────────────┬───────┬───────┬───────┬─────┬──────┬─────┬──────┐
42 | │ name │ lines │ comm. │ cont. │ acs │ acsr │ wpc │ wpcr │
43 | ├─────────────────────────────────────────────┼───────┼───────┼───────┼─────┼──────┼─────┼──────┤
44 | │ Actions/GameAndRandomClipsSample.php │ 55 │ 2 │ 1 │ 27 │ 49 │ 55 │ 100 │
45 | │ Console/Kernel.php │ 27 │ 1 │ 1 │ 27 │ 100 │ 27 │ 100 │
46 | │ Dtos/Uuid.php │ 37 │ 3 │ 1 │ 12 │ 32 │ 37 │ 100 │
47 | │ Enums/AutoplayEnum.php │ 9 │ 1 │ 1 │ 9 │ 100 │ 9 │ 100 │
48 | │ Enums/ClipStateEnum.php │ 15 │ 2 │ 1 │ 7 │ 46 │ 15 │ 100 │
49 | │ Exceptions/AssertException.php │ 10 │ 1 │ 1 │ 10 │ 100 │ 10 │ 100 │
50 | │ Exceptions/Handler.php │ 35 │ 4 │ 1 │ 8 │ 22 │ 35 │ 100 │
51 | │ Http/Controllers/Controller.php │ 12 │ 1 │ 1 │ 12 │ 100 │ 12 │ 100 │
52 | │ Http/Controllers/HomeController.php │ 37 │ 9 │ 2 │ 4 │ 10 │ 18 │ 48 │
53 | │ Http/Controllers/PaginateClipController.php │ 48 │ 8 │ 2 │ 6 │ 12 │ 24 │ 50 │
54 | └─────────────────────────────────────────────┴───────┴───────┴───────┴─────┴──────┴─────┴──────┘
55 | ```
56 |
57 | Understanding analysis :
58 |
59 | | Abbreviation | Metric | Description |
60 | | ------------ | ------------------------------ | ------------------------------------------------------------------------------ |
61 | | comm. | Commits | Number of file commits. |
62 | | cont. | Contributors | Number of distinct contributors. |
63 | | acs | Average Commit Size | Average size of file commits. |
64 | | acsr | Average Commit Size Ratio | Proportion of average commit size compared to the total file size. |
65 | | wpc | Workload Per Contributor | Average size of a contributor's commits. |
66 | | wpcr | Workload Per Contributor Ratio | Proportion of average contributor commit size compared to the total file size. |
67 |
68 | ## Options
69 |
70 | | Options | Description |
71 | |-----------------------|-------------|
72 | | --folder= | Filter results by folder (e.g., --folder=Http/Controllers).|
73 | | --limit= | Specify the maximum number of results to display (default is 10).|
74 | | --sorts= | Sets the sorting order for results. The first value (lines, commits, contributors, acs, acsr, wpc, wpcr) corresponds to the affected field, and the second value (desc,asc; default desc) determines the sorting order.|
75 | | --thresholds= | Sets a threshold for the specified metric to filter results. The first value (lines, commits, contributors, acs, acsr, wpc, wpcr) corresponds to the affected metric, and the second value (e.g., 60) represents the minimum value required to apply the threshold.|
76 |
77 | ## Examples
78 |
79 | Files with more than 300 lines and low contributor diversity :
80 |
81 | ```
82 | php php-git-insights-analyzer app:report --limit=10 --thresholds=wpcr,60 --thresholds=lines,300
83 | ```
84 |
85 | Files with more than 10 commits and low contributor diversity :
86 |
87 | ```
88 | php php-git-insights-analyzer app:report --limit=10 --thresholds=wpcr,60 --thresholds=commits,10
89 | ```
90 |
91 | File with more than 10 commits and a renewal ratio of 10% with each commit.
92 |
93 | ```
94 | php php-git-insights-analyzer app:report --limit=10 --thresholds=acsr,10 --thresholds=commits,10
95 | ```
96 |
97 | > [!TIP]
98 | > Other analysis [tools](https://github.com/DeGraciaMathieu) are available.
99 |
--------------------------------------------------------------------------------
/app/Application/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeGraciaMathieu/php-git-insights-analyzer/9b94a4f4aa6a615a31d38e4c0ba92ec04fe578e6/app/Application/.gitkeep
--------------------------------------------------------------------------------
/app/Application/Load/LoadHandler.php:
--------------------------------------------------------------------------------
1 | hello();
30 |
31 | $output->inProgress();
32 |
33 | $aggregator = $this->trackedFileService->all(
34 | new Path($request->path()),
35 | );
36 |
37 | $this->trackedFileAnalyzer->analyze($aggregator);
38 |
39 | $this->trackedFileRepository->store($aggregator);
40 |
41 | $output->present();
42 |
43 | } catch (Throwable $th) {
44 | $output->error($th);
45 | }
46 | }
47 | }
--------------------------------------------------------------------------------
/app/Application/Load/LoadOutputInterface.php:
--------------------------------------------------------------------------------
1 | hello();
25 |
26 | $reportAggregator = $this->reportGenerator->make();
27 |
28 | $output->present($reportAggregator);
29 |
30 | } catch (Throwable $th) {
31 | $output->error($th);
32 | }
33 | }
34 | }
--------------------------------------------------------------------------------
/app/Application/Report/ReportOutputInterface.php:
--------------------------------------------------------------------------------
1 | reportLines[] = $reportLine;
17 | }
18 |
19 | public function toArray(): array
20 | {
21 | return array_map(function (ReportLine $reportLine) {
22 | return $reportLine->toArray();
23 | }, $this->reportLines);
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/app/Domain/Aggregators/TrackedFileAggregator.php:
--------------------------------------------------------------------------------
1 | path = $path;
19 | }
20 |
21 | public function add(TrackedFile $trackedFile): void
22 | {
23 | $this->trackedFiles[] = $trackedFile;
24 | }
25 |
26 | public function path(): Path|null
27 | {
28 | return $this->path;
29 | }
30 |
31 | public function trackedFiles(): array
32 | {
33 | return $this->trackedFiles;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/Domain/Contracts/Gateways/FileVersionControlGateway.php:
--------------------------------------------------------------------------------
1 |
12 | */
13 | public function get(): array;
14 |
15 | public function store(TrackedFileAggregator $aggregator): void;
16 | }
17 |
--------------------------------------------------------------------------------
/app/Domain/Entities/Analysis.php:
--------------------------------------------------------------------------------
1 | value = $value ?: 1;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/Domain/Entities/Path.php:
--------------------------------------------------------------------------------
1 | name = $name;
21 |
22 | $this->load($analysis);
23 |
24 | $this->computeAverageSize();
25 |
26 | $this->computeWorkloadPerContributor();
27 | }
28 |
29 | private function load(Analysis $analysis): void
30 | {
31 | $this->totalLines = $analysis->totalLine->value;
32 | $this->totalCommits = $analysis->commitsCount->value;
33 | $this->totalContributors = $analysis->contributorsCount->value;
34 | }
35 |
36 | private function computeAverageSize(): void
37 | {
38 | $this->averageCommitSize = $this->totalLines / $this->totalCommits;
39 | $this->averageCommitSizeRatio = $this->averageCommitSize * 100 / $this->totalLines;
40 | }
41 |
42 | private function computeWorkloadPerContributor(): void
43 | {
44 | $this->workloadPerContributor = $this->totalLines / $this->totalContributors;
45 | $this->workloadPerContributorRatio = $this->workloadPerContributor * 100 / $this->totalLines;
46 | }
47 |
48 | public function toArray(): array
49 | {
50 | return get_object_vars($this);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/app/Domain/Entities/TrackedFile.php:
--------------------------------------------------------------------------------
1 | trackedFileRepository->get();
20 |
21 | foreach ($trackedFiles as $trackedFile) {
22 |
23 | $reportLine = new ReportLine(
24 | name: $trackedFile->name,
25 | analysis: $trackedFile->analysis,
26 | );
27 |
28 | $this->aggregator->add($reportLine);
29 | }
30 |
31 | return $this->aggregator;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/Domain/Services/TrackedFileAnalyzer.php:
--------------------------------------------------------------------------------
1 | trackedFiles();
18 |
19 | foreach ($trackedFiles as $trackedFile) {
20 |
21 | $analysis = $this->fileVersionControl->analyze($trackedFile);
22 |
23 | $trackedFile->analysis = $analysis;
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/Domain/Services/TrackedFileService.php:
--------------------------------------------------------------------------------
1 | aggregator->setPath($path);
21 |
22 | $names = $this->fileVersionControl->allTrackedFilesName($path);
23 |
24 | foreach ($names as $name) {
25 |
26 | $trackedFile = new TrackedFile($name);
27 |
28 | $this->aggregator->add($trackedFile);
29 | }
30 |
31 | return $this->aggregator;
32 | }
33 | }
--------------------------------------------------------------------------------
/app/Infrastructure/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeGraciaMathieu/php-git-insights-analyzer/9b94a4f4aa6a615a31d38e4c0ba92ec04fe578e6/app/Infrastructure/.gitkeep
--------------------------------------------------------------------------------
/app/Infrastructure/Gateways/CliGitGateway.php:
--------------------------------------------------------------------------------
1 | value);
17 |
18 | $cmdFiles = "git ls-files '*.php'";
19 |
20 | $names = explode("\n", trim(shell_exec($cmdFiles)));
21 |
22 | return $names;
23 | }
24 |
25 | public function analyze(TrackedFile $trackedFile): Analysis
26 | {
27 | $name = $trackedFile->name;
28 |
29 | $cdm = "git log --pretty=format:'%an' -- " . $name . "| awk '!seen[$0]++ { contributors++ } END { print contributors }' && git log --oneline -- $name | wc -l";
30 |
31 | $output = trim(shell_exec($cdm));
32 |
33 | [$contributorsCount, $commitsCount] = explode("\n", trim($output));
34 |
35 | $lines = file($name);
36 |
37 | $totalLine = count($lines) ?: 0;
38 |
39 | return new Analysis(
40 | totalLine: new Metric($totalLine),
41 | commitsCount: new Metric($commitsCount),
42 | contributorsCount: new Metric($contributorsCount),
43 | );
44 | }
45 | }
--------------------------------------------------------------------------------
/app/Infrastructure/Repositories/TrackedFileStorageRepository.php:
--------------------------------------------------------------------------------
1 | makeStorageFileName();
20 |
21 | $trackedFiles = $aggregator->trackedFiles();
22 |
23 | $this->filesystem->put($storageFileName, serialize($trackedFiles));
24 | }
25 |
26 | /**
27 | * @return array
28 | */
29 | public function get(): array
30 | {
31 | $storageFileName = $this->makeStorageFileName();
32 |
33 | $trackedFiles = $this->filesystem->get($storageFileName);
34 |
35 | if ($trackedFiles === null) {
36 | throw new Exception('Please, run app:load command before.');
37 | }
38 |
39 | return unserialize($trackedFiles);
40 | }
41 |
42 | private function makeStorageFileName(): string
43 | {
44 | return 'analyse.json';
45 | }
46 | }
--------------------------------------------------------------------------------
/app/Presenter/Commands/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeGraciaMathieu/php-git-insights-analyzer/9b94a4f4aa6a615a31d38e4c0ba92ec04fe578e6/app/Presenter/Commands/.gitkeep
--------------------------------------------------------------------------------
/app/Presenter/Commands/Load/LoadCliOutput.php:
--------------------------------------------------------------------------------
1 | getMessage());
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/Presenter/Commands/Load/LoadCliRequest.php:
--------------------------------------------------------------------------------
1 | path;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/app/Presenter/Commands/Load/LoadCommand.php:
--------------------------------------------------------------------------------
1 | handle(
34 | new LoadCliRequest(
35 | path: $this->argument('path'),
36 | ),
37 | new LoadCliOutput(),
38 | );
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Presenter/Commands/Report/Cli/Concerns/Sorts.php:
--------------------------------------------------------------------------------
1 | sorts === []
10 | ? $this->getDefaultSorting()
11 | : $this->sanitizeSortingPairing();
12 | }
13 |
14 | private function getDefaultSorting(): array
15 | {
16 | return [
17 | 'totalCommits',
18 | 'desc',
19 | ];
20 | }
21 |
22 | private function sanitizeSortingPairing(): array
23 | {
24 | return array_map(function ($sort) {
25 |
26 | [$sortKey, $sortValue] = explode(',', $sort);
27 |
28 | $sortValue ??= 'desc';
29 |
30 | return [
31 | $this->mapIdentifier($sortKey),
32 | $sortValue,
33 | ];
34 |
35 | }, $this->sorts);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/app/Presenter/Commands/Report/Cli/Concerns/Thresholds.php:
--------------------------------------------------------------------------------
1 | thresholds === []) {
10 | return [];
11 | }
12 |
13 | return $this->sanitizeThresholdsPairing();
14 | }
15 |
16 | private function sanitizeThresholdsPairing(): ?array
17 | {
18 | return array_map(function ($threshold) {
19 |
20 | [$minKey, $minValue] = explode(',', $threshold);
21 |
22 | return [
23 | $this->mapIdentifier($minKey),
24 | $minValue,
25 | ];
26 |
27 | }, $this->thresholds);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/app/Presenter/Commands/Report/Cli/ReportCliOutput.php:
--------------------------------------------------------------------------------
1 | toArray());
28 |
29 | $rows = $this->sort($rows);
30 |
31 | $rows = $this->cut($rows);
32 |
33 | $this->display($rows);
34 | }
35 |
36 | public function error(Throwable $throwable): void
37 | {
38 | error($throwable->getMessage());
39 |
40 | error('Maybe run app:load again ?');
41 | }
42 |
43 | private function sort(Collection $rows): Collection
44 | {
45 | $sorts = $this->options->getSorts();
46 |
47 | $rows = $rows->sortBy($sorts);
48 |
49 | return $rows;
50 | }
51 |
52 | private function cut(Collection $rows): Collection
53 | {
54 | $rows = $this->cuttingFolder($rows);
55 |
56 | $rows = $this->cuttingThresholds($rows);
57 |
58 | return $rows->take($this->options->getLimit());
59 | }
60 |
61 | private function cuttingFolder(Collection $rows): Collection
62 | {
63 | $rows = $rows->filter(function ($row) {
64 |
65 | if ($folder = $this->options->getFolder()) {
66 | return str_starts_with($row['name'], $folder);
67 | }
68 |
69 | return true;
70 | });
71 |
72 | return $rows;
73 | }
74 |
75 | private function cuttingThresholds(Collection $rows): Collection
76 | {
77 | $rows = $rows->filter(function ($row) {
78 |
79 | $thresholds = $this->options->getThresholds();
80 |
81 | foreach ($thresholds as $threshold) {
82 |
83 | [$key, $value] = $threshold;
84 |
85 | if ($row[$key] < $value) {
86 | return false;
87 | }
88 | }
89 |
90 | return true;
91 | });
92 |
93 | return $rows;
94 | }
95 |
96 | private function display(Collection $rows): void
97 | {
98 | table(
99 | [
100 | 'name',
101 | 'lines',
102 | 'comm.',
103 | 'cont.',
104 | 'acs',
105 | 'acsr%',
106 | 'wpc',
107 | 'wpcr%',
108 | ],
109 | $rows,
110 | );
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/app/Presenter/Commands/Report/Cli/ReportCliRequest.php:
--------------------------------------------------------------------------------
1 | folder;
20 | }
21 |
22 | public function getLimit(): int|null
23 | {
24 | return $this->limit;
25 | }
26 |
27 | protected function mapIdentifier(string $key): string
28 | {
29 | return match ($key) {
30 | 'lines' => 'totalLines',
31 | 'commits' => 'totalCommits',
32 | 'contributors' => 'totalContributors',
33 | 'acs' => 'averageCommitSize',
34 | 'acsr' => 'averageCommitSizeRatio',
35 | 'wpc' => 'workloadPerContributor',
36 | 'wpcr' => 'workloadPerContributorRatio',
37 | default => 'totalCommits',
38 | };
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/Presenter/Commands/Report/ReportCommand.php:
--------------------------------------------------------------------------------
1 | option('folder'),
39 | limit: $this->option('limit'),
40 | sorts: $this->option('sorts'),
41 | thresholds: $this->option('thresholds'),
42 | );
43 |
44 | $reportHandler->handle(
45 | new ReportCliRequest(),
46 | new ReportCliOutput($options),
47 | );
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/app/Providers/AppServiceProvider.php:
--------------------------------------------------------------------------------
1 | app->singleton(FileVersionControlGateway::class, function ($app) {
29 |
30 | $aggregator = $app[TrackedFileAggregator::class];
31 |
32 | return new CliGitGateway($aggregator);
33 | });
34 |
35 | $this->app->singleton(TrackedFileRepository::class, function ($app) {
36 |
37 | $filesystem = $app[FilesystemManager::class];
38 |
39 | return new TrackedFileStorageRepository($filesystem);
40 | });
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/bootstrap/app.php:
--------------------------------------------------------------------------------
1 | singleton(
30 | Illuminate\Contracts\Console\Kernel::class,
31 | LaravelZero\Framework\Kernel::class
32 | );
33 |
34 | $app->singleton(
35 | Illuminate\Contracts\Debug\ExceptionHandler::class,
36 | Illuminate\Foundation\Exceptions\Handler::class
37 | );
38 |
39 | /*
40 | |--------------------------------------------------------------------------
41 | | Return The Application
42 | |--------------------------------------------------------------------------
43 | |
44 | | This script returns the application instance. The instance is given to
45 | | the calling script so we can separate the building of the instances
46 | | from the actual running of the application and sending responses.
47 | |
48 | */
49 |
50 | return $app;
51 |
--------------------------------------------------------------------------------
/box.json:
--------------------------------------------------------------------------------
1 | {
2 | "chmod": "0755",
3 | "directories": [
4 | "app",
5 | "bootstrap",
6 | "config",
7 | "vendor"
8 | ],
9 | "files": [
10 | "composer.json"
11 | ],
12 | "exclude-composer-files": false,
13 | "compression": "GZ",
14 | "compactors": [
15 | "KevinGH\\Box\\Compactor\\Php",
16 | "KevinGH\\Box\\Compactor\\Json"
17 | ]
18 | }
19 |
--------------------------------------------------------------------------------
/builds/php-git-insights-analyzer:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DeGraciaMathieu/php-git-insights-analyzer/9b94a4f4aa6a615a31d38e4c0ba92ec04fe578e6/builds/php-git-insights-analyzer
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "laravel-zero/laravel-zero",
3 | "description": "The Laravel Zero Framework.",
4 | "keywords": ["framework", "laravel", "laravel zero", "console", "cli"],
5 | "homepage": "https://laravel-zero.com",
6 | "type": "project",
7 | "license": "MIT",
8 | "support": {
9 | "issues": "https://github.com/laravel-zero/laravel-zero/issues",
10 | "source": "https://github.com/laravel-zero/laravel-zero"
11 | },
12 | "authors": [
13 | {
14 | "name": "Nuno Maduro",
15 | "email": "enunomaduro@gmail.com"
16 | }
17 | ],
18 | "require": {
19 | "php": "^8.1",
20 | "laravel-zero/framework": "^10.2",
21 | "nunomaduro/termwind": "^1.15.1"
22 | },
23 | "require-dev": {
24 | "laravel/pint": "^1.13",
25 | "mockery/mockery": "^1.6",
26 | "pestphp/pest": "^2.22"
27 | },
28 | "autoload": {
29 | "psr-4": {
30 | "App\\": "app/",
31 | "Database\\Factories\\": "database/factories/",
32 | "Database\\Seeders\\": "database/seeders/"
33 | }
34 | },
35 | "autoload-dev": {
36 | "psr-4": {
37 | "Tests\\": "tests/"
38 | }
39 | },
40 | "config": {
41 | "preferred-install": "dist",
42 | "sort-packages": true,
43 | "optimize-autoloader": true,
44 | "allow-plugins": {
45 | "pestphp/pest-plugin": true
46 | }
47 | },
48 | "minimum-stability": "stable",
49 | "prefer-stable": true,
50 | "bin": ["php-git-insights-analyzer"]
51 | }
52 |
--------------------------------------------------------------------------------
/config/app.php:
--------------------------------------------------------------------------------
1 | 'Php-git-insights-analyzer',
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Application Version
21 | |--------------------------------------------------------------------------
22 | |
23 | | This value determines the "version" your application is currently running
24 | | in. You may want to follow the "Semantic Versioning" - Given a version
25 | | number MAJOR.MINOR.PATCH when an update happens: https://semver.org.
26 | |
27 | */
28 |
29 | 'version' => app('git.version'),
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Application Environment
34 | |--------------------------------------------------------------------------
35 | |
36 | | This value determines the "environment" your application is currently
37 | | running in. This may determine how you prefer to configure various
38 | | services the application utilizes. This can be overridden using
39 | | the global command line "--env" option when calling commands.
40 | |
41 | */
42 |
43 | 'env' => 'development',
44 |
45 | /*
46 | |--------------------------------------------------------------------------
47 | | Application Timezone
48 | |--------------------------------------------------------------------------
49 | |
50 | | Here you may specify the default timezone for your application, which
51 | | will be used by the PHP date and date-time functions. We have gone
52 | | ahead and set this to a sensible default for you out of the box.
53 | |
54 | */
55 |
56 | 'timezone' => 'UTC',
57 |
58 | /*
59 | |--------------------------------------------------------------------------
60 | | Autoloaded Service Providers
61 | |--------------------------------------------------------------------------
62 | |
63 | | The service providers listed here will be automatically loaded on the
64 | | request to your application. Feel free to add your own services to
65 | | this array to grant expanded functionality to your applications.
66 | |
67 | */
68 |
69 | 'providers' => [
70 | App\Providers\AppServiceProvider::class,
71 | ],
72 |
73 | ];
74 |
--------------------------------------------------------------------------------
/config/commands.php:
--------------------------------------------------------------------------------
1 | NunoMaduro\LaravelConsoleSummary\SummaryCommand::class,
17 |
18 | /*
19 | |--------------------------------------------------------------------------
20 | | Commands Paths
21 | |--------------------------------------------------------------------------
22 | |
23 | | This value determines the "paths" that should be loaded by the console's
24 | | kernel. Foreach "path" present on the array provided below the kernel
25 | | will extract all "Illuminate\Console\Command" based class commands.
26 | |
27 | */
28 |
29 | 'paths' => [app_path('Presenter/Commands')],
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Added Commands
34 | |--------------------------------------------------------------------------
35 | |
36 | | You may want to include a single command class without having to load an
37 | | entire folder. Here you can specify which commands should be added to
38 | | your list of commands. The console's kernel will try to load them.
39 | |
40 | */
41 |
42 | 'add' => [
43 | // ..
44 | ],
45 |
46 | /*
47 | |--------------------------------------------------------------------------
48 | | Hidden Commands
49 | |--------------------------------------------------------------------------
50 | |
51 | | Your application commands will always be visible on the application list
52 | | of commands. But you can still make them "hidden" specifying an array
53 | | of commands below. All "hidden" commands can still be run/executed.
54 | |
55 | */
56 |
57 | 'hidden' => [
58 | NunoMaduro\LaravelConsoleSummary\SummaryCommand::class,
59 | Symfony\Component\Console\Command\DumpCompletionCommand::class,
60 | Symfony\Component\Console\Command\HelpCommand::class,
61 | Illuminate\Console\Scheduling\ScheduleRunCommand::class,
62 | Illuminate\Console\Scheduling\ScheduleListCommand::class,
63 | Illuminate\Console\Scheduling\ScheduleFinishCommand::class,
64 | Illuminate\Foundation\Console\VendorPublishCommand::class,
65 | LaravelZero\Framework\Commands\StubPublishCommand::class,
66 | ],
67 |
68 | /*
69 | |--------------------------------------------------------------------------
70 | | Removed Commands
71 | |--------------------------------------------------------------------------
72 | |
73 | | Do you have a service provider that loads a list of commands that
74 | | you don't need? No problem. Laravel Zero allows you to specify
75 | | below a list of commands that you don't to see in your app.
76 | |
77 | */
78 |
79 | 'remove' => [
80 | // ..
81 | ],
82 |
83 | ];
84 |
--------------------------------------------------------------------------------
/config/filesystems.php:
--------------------------------------------------------------------------------
1 | 'local',
5 | 'disks' => [
6 | 'local' => [
7 | 'driver' => 'local',
8 | 'root' => getcwd(),
9 | ],
10 | ],
11 | ];
12 |
--------------------------------------------------------------------------------
/php-git-insights-analyzer:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | make(Illuminate\Contracts\Console\Kernel::class);
34 |
35 | $status = $kernel->handle(
36 | $input = new Symfony\Component\Console\Input\ArgvInput,
37 | new Symfony\Component\Console\Output\ConsoleOutput
38 | );
39 |
40 | /*
41 | |--------------------------------------------------------------------------
42 | | Shutdown The Application
43 | |--------------------------------------------------------------------------
44 | |
45 | | Once Artisan has finished running, we will fire off the shutdown events
46 | | so that any final work may be done by the application before we shut
47 | | down the process. This is the last thing to happen to the request.
48 | |
49 | */
50 |
51 | $kernel->terminate($input, $status);
52 |
53 | exit($status);
54 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
9 | ./tests/Feature
10 |
11 |
12 | ./tests/Unit
13 |
14 |
15 |
16 |
17 | ./app
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/tests/CreatesApplication.php:
--------------------------------------------------------------------------------
1 | make(Kernel::class)->bootstrap();
18 |
19 | return $app;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tests/Feature/InspireCommandTest.php:
--------------------------------------------------------------------------------
1 | artisan('inspire')->assertExitCode(0);
5 | });
6 |
--------------------------------------------------------------------------------
/tests/Pest.php:
--------------------------------------------------------------------------------
1 | in('Feature');
15 |
16 | /*
17 | |--------------------------------------------------------------------------
18 | | Expectations
19 | |--------------------------------------------------------------------------
20 | |
21 | | When you're writing tests, you often need to check that values meet certain conditions. The
22 | | "expect()" function gives you access to a set of "expectations" methods that you can use
23 | | to assert different things. Of course, you may extend the Expectation API at any time.
24 | |
25 | */
26 |
27 | expect()->extend('toBeOne', function () {
28 | return $this->toBe(1);
29 | });
30 |
31 | /*
32 | |--------------------------------------------------------------------------
33 | | Functions
34 | |--------------------------------------------------------------------------
35 | |
36 | | While Pest is very powerful out-of-the-box, you may have some testing code specific to your
37 | | project that you don't want to repeat in every file. Here you can also expose helpers as
38 | | global functions to help you to reduce the number of lines of code in your test files.
39 | |
40 | */
41 |
42 | function something(): void
43 | {
44 | // ..
45 | }
46 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | toBeTrue();
5 | });
6 |
--------------------------------------------------------------------------------