Installation:
composer require-dev c975l/countlinescode-bundle
Ensure this is added to require-dev in composer.json for CI/CD or local dev environments.
Configuration:
Create /config/packages/dev/count_lines_codes.yaml (or merge into existing dev config):
c975LCountLinesCode:
folders: ['src', 'templates'] # Start with core directories
extensions: ['php', 'twig'] # Focus on primary languages
First Run:
php bin/console count:loc
Outputs a summary of lines of code (LOC) per file type and directory.
dev pipeline to track LOC growth over time (e.g., via php bin/console count:loc --format=json).README.md with LOC stats.Custom Reports: Extend the command to output structured data (e.g., CSV/JSON) for dashboards:
// In a custom command or service
$locService = $container->get('c975l_count_lines_code.loc_service');
$results = $locService->countLinesOfCode();
file_put_contents('loc_report.json', json_encode($results));
Excluding Directories:
Use folders config to exclude vendor/, node_modules/, or tests/:
folders: ['src', 'templates']
# Explicitly omit tests/ to focus on production code
Integration with Tests:
Add a post-test hook in phpunit.xml to log LOC changes:
<phpunit>
<listeners>
<listener class="App\Listener\LocChangeListener" file="tests/Listener/LocChangeListener.php"/>
</listeners>
</phpunit>
// LocChangeListener.php
public function postTestSuite(PostTestSuiteEvent $event) {
$loc = shell_exec('php bin/console count:loc --format=json');
file_put_contents('tests/loc_after_tests.json', $loc);
}
Symfony Flex Compatibility:
If using Symfony 4.3+, ensure the bundle is loaded in config/bundles.php:
return [
// ...
C975L\CountLinesCodeBundle\C975LCountLinesCodeBundle::class => ['dev' => true],
];
pre-commit to alert on LOC spikes:
# .git/hooks/pre-commit
php bin/console count:loc --format=json | jq '.total' > /tmp/loc_total
git diff --numstat | awk '{add+=$1} END {print add}' > /tmp/loc_diff
if [ $(cat /tmp/loc_diff) -gt 500 ]; then
echo "LOC change exceeds threshold!" >&2
exit 1
fi
dev container to avoid host filesystem issues:
# Dockerfile.dev
RUN composer require-dev c975l/countlinescode-bundle
CMD ["php", "bin/console", "count:loc"]
Performance:
folders: ['.']). Stick to src/ and templates/.var/cache/dev/loc_cache.json to avoid repeated scans:
# config/packages/dev/count_lines_codes.yaml
c975LCountLinesCode:
cache: true
False Positives:
{% extends %}, {% block %}, and comments from counts by overriding the parser:
extensions:
twig: { exclude_patterns: ['{%.*%}', '{#.*#}'] }
var/cache/*) by adding to folders:
folders: ['src', 'templates']
exclude_folders: ['var/', 'node_modules/']
Symfony 5+ Deprecations:
php bin/console debug:container | grep count_lines_code
Command Output:
--format=json for automation:
php bin/console count:loc --format=json | jq '.files[] | {path, lines}'
Verbose Mode:
php bin/console count:loc -vvv
Reveals skipped files and parsing issues.
Log Parsing Errors:
Enable monolog in config/packages/dev/monolog.yaml to catch edge cases:
handlers:
count_lines:
type: stream
path: var/log/count_lines.log
level: debug
Custom File Types:
Extend the FileType class to support new languages (e.g., YAML for Symfony config):
// src/Service/CountLinesCode/CustomFileType.php
namespace App\Service\CountLinesCode;
use C975L\CountLinesCodeBundle\Service\CountLinesCode\FileType;
class CustomFileType extends FileType
{
public function __construct()
{
$this->extension = 'yaml';
$this->commentPattern = '#^#.*$#m';
}
}
Register in services.yaml:
services:
App\Service\CountLinesCode\CustomFileType:
tags: { name: c975l_count_lines_code.file_type }
Pre/Post-Processing:
Hook into the CountLinesCodeEvent (if available) to modify results:
// src/EventListener/LocListener.php
namespace App\EventListener;
use C975L\CountLinesCodeBundle\Event\CountLinesCodeEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
CountLinesCodeEvent::NAME => 'onCountLinesCode',
];
}
public function onCountLinesCode(CountLinesCodeEvent $event)
{
$results = $event->getResults();
$results['metadata']['processed_at'] = new \DateTime();
$event->setResults($results);
}
}
Parallel Processing:
For large codebases, override the LocService to use parallel workers (e.g., ReactPHP):
// src/Service/ParallelLocService.php
use C975L\CountLinesCodeBundle\Service\LocService as BaseLocService;
class ParallelLocService extends BaseLocService
{
protected function countLinesInFile(string $file): int
{
// Implement parallel logic here
}
}
Bind in services.yaml:
services:
C975L\CountLinesCodeBundle\Service\LocService:
alias: App\Service\ParallelLocService
How can I help you explore Laravel packages today?