1
0
mirror of https://github.com/pgbackrest/pgbackrest.git synced 2024-12-12 10:04:14 +02:00

Generate code counts for all source files.

The source files are also classified by type and purpose.
This commit is contained in:
David Steele 2018-04-16 15:52:17 -04:00
parent 3e22977484
commit dce11ce3cf
6 changed files with 1538 additions and 1 deletions

View File

@ -136,6 +136,10 @@
<p>Add <code>harnessCfgLoad()</code> test function, which allows a new config to be loaded for unit testing without resetting log functions, opening a log file, or taking locks.</p>
</release-item>
<release-item>
<p>Generate code counts for all source files. The source files are also classified by type and purpose.</p>
</release-item>
<release-item>
<p>Include VM type in <id>gcov</id> path to avoid conflicts between VMs with different architectures.</p>
</release-item>

2
test/Vagrantfile vendored
View File

@ -52,7 +52,7 @@ Vagrant.configure(2) do |config|
#---------------------------------------------------------------------------------------------------------------------------
echo 'Install Build Tools' && date
apt-get install -y devscripts build-essential lintian git txt2man debhelper libssl-dev lcov
apt-get install -y devscripts build-essential lintian git txt2man debhelper libssl-dev lcov cloc
#---------------------------------------------------------------------------------------------------------------------------
echo 'Install AWS CLI' && date

12
test/code-count/code.def Normal file
View File

@ -0,0 +1,12 @@
XS
filter remove_matches ^\s*//
filter call_regexp_common C
filter remove_inline //.*$
filter remove_inline #.*$
extension xs
3rd_gen_scale 0.77
end_of_line_continuation \\$
Latex
filter remove_inline %.*$
extension tex
3rd_gen_scale 1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,216 @@
####################################################################################################################################
# Classify files and generate code totals
####################################################################################################################################
package pgBackRestTest::Common::CodeCountTest;
####################################################################################################################################
# Perl includes
####################################################################################################################################
use strict;
use warnings FATAL => qw(all);
use Carp qw(confess);
use English '-no_match_vars';
use Exporter qw(import);
our @EXPORT = qw();
use pgBackRest::Common::Log;
use pgBackRestTest::Common::ExecuteTest;
####################################################################################################################################
# Scan all files and assign types
####################################################################################################################################
sub codeCountScan
{
my $oStorage = shift;
my $strBasePath = shift;
# Load YAML
require YAML::XS;
YAML::XS->import(qw(Load Dump));
my $hCodeCount = {};
# Build manifest of all files
my $hManifest = $oStorage->manifest($strBasePath);
my $strYamlDetail = undef;
foreach my $strFile (sort(keys(%{$hManifest})))
{
# Only interested in files
next if $hManifest->{$strFile}{type} ne 'f';
# Only exclude these directories/files entirely
next if ($strFile =~ '^\.' ||
$strFile =~ '\.md$' ||
$strFile =~ '\.log$' ||
$strFile eq 'LICENSE' ||
$strFile =~ '^doc/example/' ||
$strFile =~ '^doc/output/' ||
$strFile =~ '\.png$' ||
$strFile =~ '\.eps$' ||
$strFile =~ '\.cache$' ||
$strFile =~ '^doc/site/' ||
$strFile eq 'libc/typemap' ||
$strFile eq 'test/Vagrantfile' ||
$strFile =~ '^test/code-count/' ||
$strFile =~ '^test/coverage/' ||
$strFile =~ '^test/data/' ||
$strFile =~ '^test/expect/' ||
$strFile =~ '^test/lint/' ||
$strFile =~ '^test/package/' ||
$strFile eq 'test/src/valgrind.suppress' ||
$strFile eq 'test/src/lcov.conf');
# Classify the souce file
my $strClass = 'test/harness';
if ($strFile =~ '^doc/xml/' || $strFile eq 'doc/manifest.xml')
{
$strClass = 'doc/source';
}
elsif ($strFile =~ '^doc/' || $strFile =~ '^doc/resource/')
{
$strClass = 'doc/core';
}
elsif ($strFile =~ '^build/' || $strFile =~ '^libc/build/' || $strFile eq 'libc/Makefile.PL' || $strFile eq 'src/Makefile')
{
$strClass = 'build';
}
elsif ($strFile =~ '^test/lib/pgBackRestTest/Module/' || $strFile =~ '^test/src/module/' ||
$strFile =~ '^libc/t/')
{
$strClass = 'test/module';
}
elsif ($strFile =~ '^src/' || $strFile =~ '^lib/' || $strFile =~ '^libc/')
{
if ($strFile =~ '\.auto\..$' || $strFile =~ 'Auto\.pm$')
{
$strClass = 'core/auto';
}
else
{
$strClass = 'core';
}
}
# Force unrecognized file types
my $strForceLang = undef;
my $strType = undef;
if ($strFile =~ '\.xs$')
{
$strType = 'xs';
$strForceLang = 'XS';
}
elsif ($strFile =~ '\.h$' || $strFile =~ '\.xsh$')
{
$strType = 'c/h';
$strForceLang = 'C/C++ Header';
}
elsif ($strFile =~ '\.c$')
{
$strType = 'c';
$strForceLang = 'C';
}
elsif ($strFile =~ '\.t$' || $strFile =~ '\.pl$' || $strFile =~ '\.pm$' || $strFile =~ '\.PL$')
{
$strType = 'perl';
$strForceLang = 'Perl';
}
elsif ($strFile =~ '\.yaml$')
{
$strType = 'yaml';
$strForceLang = 'YAML';
}
elsif ($strFile =~ 'Makefile$')
{
$strType = 'make';
$strForceLang = 'make';
}
elsif ($strFile =~ '\.xml$')
{
$strType = 'xml';
$strForceLang = 'XML';
}
elsif ($strFile =~ '\.css$')
{
$strType = 'css';
$strForceLang = 'CSS';
}
elsif ($strFile =~ '\.dtd$')
{
$strType = 'dtd';
$strForceLang = 'DTD';
}
elsif ($strFile =~ '\.tex$')
{
$strType = 'latex';
$strForceLang = 'Latex';
}
else
{
confess &log(ERROR, "unable to map type for ${strFile}");
}
# Load the file counts
my $strYaml = executeTest(
"cloc --yaml ${strBasePath}/${strFile}" .
" --read-lang-def=${strBasePath}/test/code-count/code.def" .
" --force-lang='${strForceLang}'");
# Error if the file was ignored
if ($strYaml =~ '1 file ignored')
{
confess &log(ERROR, "file type for ${strBasePath}/${strFile} not recognized:\n${strYaml}");
}
# Clean out extraneous keys
my $hFileCount = Load($strYaml);
delete($hFileCount->{header});
delete($hFileCount->{SUM});
# There should only be one key - the file type
if (keys(%{$hFileCount}) != 1)
{
confess &log(ERROR, "more than one file type in ${strBasePath}/${strFile}:\n" . Dump($hFileCount));
}
# Translate type
my ($strTypeRaw) = keys(%{$hFileCount});
$hFileCount = $hFileCount->{$strTypeRaw};
# Append to yaml file
$strYamlDetail .=
(defined($strYamlDetail) ? "\n" : '') .
"${strFile}:\n" .
" class: ${strClass}\n" .
" type: ${strType}\n";
# Summarize
$hCodeCount->{$strClass}{$strType}{code} += $hFileCount->{code};
$hCodeCount->{$strClass}{$strType}{comment} += $hFileCount->{comment};
$hCodeCount->{$strClass}{total}{code} += $hFileCount->{code};
$hCodeCount->{$strClass}{total}{comment} += $hFileCount->{comment};
$hCodeCount->{total}{code} += $hFileCount->{code};
$hCodeCount->{total}{comment} += $hFileCount->{comment};
}
# Save the file
$oStorage->put(
'test/code-count/file-type.yaml',
"# File types for source files in the project\n" . $strYamlDetail);
# Reload the file to make sure there aren't any formatting issues
Load(${$oStorage->get('test/code-count/file-type.yaml')});
# Display code count summary
&log(INFO, "code count summary:\n" . Dump($hCodeCount));
}
push @EXPORT, qw(codeCountScan);
1;

View File

@ -46,6 +46,7 @@ use pgBackRestBuild::Error::Build;
use pgBackRestBuild::Error::Data;
use pgBackRestTest::Common::BuildTest;
use pgBackRestTest::Common::CodeCountTest;
use pgBackRestTest::Common::ContainerTest;
use pgBackRestTest::Common::CiTest;
use pgBackRestTest::Common::DefineTest;
@ -81,6 +82,7 @@ test.pl [options]
--coverage-only only run coverage tests (as a subset of selected tests)
--c-only only run C tests
--gen-only only run auto-generation
--code-count generate code counts
--smart perform libc/package builds only when source timestamps have changed
--no-package do not build packages
--no-ci-config don't overwrite the current continuous integration config
@ -133,6 +135,7 @@ my $bBuildOnly = false;
my $bCoverageOnly = false;
my $bCOnly = false;
my $bGenOnly = false;
my $bCodeCount = false;
my $bSmart = false;
my $bNoPackage = false;
my $bNoCiConfig = false;
@ -167,6 +170,7 @@ GetOptions ('q|quiet' => \$bQuiet,
'coverage-only' => \$bCoverageOnly,
'c-only' => \$bCOnly,
'gen-only' => \$bGenOnly,
'code-count' => \$bCodeCount,
'smart' => \$bSmart,
'dev' => \$bDev,
'expect' => \$bExpect,
@ -305,6 +309,15 @@ eval
################################################################################################################################
if (!defined($iVmId))
{
# Generate code counts
if ($bCodeCount)
{
&log(INFO, "classify code files");
codeCountScan($oStorageBackRest, $strBackRestBase);
exit 0;
}
# Auto-generate C files
#---------------------------------------------------------------------------------------------------------------------------
&log(INFO, "check code autogenerate");