Skip to content

Commit 69eac89

Browse files
author
DKravtsov
committed
phpcpd 8.2.2 release. Improved progress bar.
1 parent f96c40b commit 69eac89

File tree

20 files changed

+252
-180
lines changed

20 files changed

+252
-180
lines changed

.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,5 @@ COMPOSE_PROJECT_NAME=phpcpd
66
# XDEBUG_CONFIG possible values: main|osx. Use main value for Linux and Windows, osx value for MacOS.
77
XDEBUG_CONFIG=main
88
# Sometimes we need to use different xdebug versions, list of versions can be found here - https://pecl.php.net/package/xdebug
9-
XDEBUG_VERSION=3.4.2
9+
XDEBUG_VERSION=3.4.3
1010
###< XDebug docker configuration ###

ChangeLog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
All notable changes in PHPCPD are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
44

5+
## [8.2.2] - 2025-05-18
6+
7+
### Updated
8+
9+
* Improved progress bar.
10+
511
## [8.2.1] - 2025-05-03
612

713
### Updated

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ ARG INSIDE_DOCKER_CONTAINER=1
1212
ENV INSIDE_DOCKER_CONTAINER=$INSIDE_DOCKER_CONTAINER
1313
ARG XDEBUG_CONFIG=main
1414
ENV XDEBUG_CONFIG=$XDEBUG_CONFIG
15-
ARG XDEBUG_VERSION=3.4.2
15+
ARG XDEBUG_VERSION=3.4.3
1616
ENV XDEBUG_VERSION=$XDEBUG_VERSION
1717
ENV PHP_CS_FIXER_IGNORE_ENV=1
1818

build.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<project name="phpcpd" default="setup">
33
<property name="basedir" value="." override="false"/>
4-
<property name="version" value="8.2.1" override="false"/>
4+
<property name="version" value="8.2.2" override="false"/>
55
<target name="setup" depends="clean,install-dependencies"/>
66

77
<target name="clean" description="Cleanup build artifacts">

composer.lock

Lines changed: 21 additions & 17 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/images/report_example_01.png

-4.54 KB
Loading

readme.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ Note: This tool is distributed as a [PHP Archive (PHAR)](https://php.net/phar).
2929
## Usage example
3030
```
3131
$ php ./vendor/bin/phpcpd --fuzzy --verbose src tests
32-
Copy/Paste Detector 8.2.1
33-
14/14 [==============================>] 100%
32+
Copy/Paste Detector 8.2.2
33+
14/14 [==============================>] 100% Loading & Processing
3434
Found 1 code clones with 17 duplicated lines in 1 files:
3535
3636
- /var/www/html/tests/Application/ApiKey/Transport/Controller/Api/v1/ApiKeyControllerTest.php:128-145 (17 lines)

releases/phpcpd-8.2.2.phar

136 KB
Binary file not shown.

releases/phpcpd-latest.phar

1.93 KB
Binary file not shown.

src/Cli/Application.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828

2929
final class Application
3030
{
31-
public const string VERSION = '8.2.1';
31+
public const string VERSION = '8.2.2';
3232

3333
/**
3434
* @param array<int, string> $argv

src/Detector/Detector.php

Lines changed: 22 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,18 @@
66

77
use Systemsdk\PhpCPD\CodeCloneMap;
88
use Systemsdk\PhpCPD\Detector\Strategy\AbstractStrategy;
9+
use Systemsdk\PhpCPD\Detector\Strategy\SuffixTreeStrategy;
10+
use Systemsdk\PhpCPD\Detector\Traits\ProgressBarTrait;
911
use Systemsdk\PhpCPD\Exceptions\ProcessingResultException;
1012

11-
use function sprintf;
12-
1313
final class Detector
1414
{
15+
use ProgressBarTrait;
16+
17+
private const int PROGRESS_BAR_BOUNDARY = 20;
18+
private const string PROGRESS_BAR_RABIN_KARP_TITLE = 'Loading & Processing';
19+
private const string PROGRESS_BAR_SUFFIX_TREE_TITLE = 'Loading';
20+
1521
public function __construct(
1622
private readonly AbstractStrategy $strategy,
1723
private readonly bool $useProgressBar = false
@@ -28,44 +34,27 @@ public function copyPasteDetection(array $files): CodeCloneMap
2834
$result = new CodeCloneMap();
2935
$totalItems = count($files);
3036
$processedFiles = 0;
37+
$boundary = self::PROGRESS_BAR_BOUNDARY;
3138
foreach ($files as $file) {
3239
$processedFiles++;
3340

34-
if (empty($file)) {
35-
$this->progressBar($processedFiles, $totalItems);
36-
37-
continue;
41+
if (!empty($file)) {
42+
$this->strategy->processFile($file, $result);
3843
}
3944

40-
$this->strategy->processFile($file, $result);
41-
$this->progressBar($processedFiles, $totalItems);
45+
if ($this->useProgressBar && $this->countProgressBarPercent($processedFiles, $totalItems) >= $boundary) {
46+
$this->progressBar(
47+
$processedFiles,
48+
$totalItems,
49+
$this->strategy instanceof SuffixTreeStrategy
50+
? self::PROGRESS_BAR_SUFFIX_TREE_TITLE
51+
: self::PROGRESS_BAR_RABIN_KARP_TITLE
52+
);
53+
$boundary += self::PROGRESS_BAR_BOUNDARY;
54+
}
4255
}
43-
$this->strategy->postProcess();
56+
$this->strategy->postProcess($this->useProgressBar);
4457

4558
return $result;
4659
}
47-
48-
private function progressBar(int $done, int $total, string $title = '', int $width = 30): void
49-
{
50-
if ($this->useProgressBar === false) {
51-
return;
52-
}
53-
54-
$perc = (int)floor(($done * 100) / $total);
55-
$bar = (int)floor(($width * $perc) / 100);
56-
57-
print sprintf(
58-
" %s/%s [%s>%s] %s%% %s\r",
59-
$done,
60-
$total,
61-
str_repeat('=', $bar),
62-
str_repeat(' ', $width - $bar),
63-
$perc,
64-
$title
65-
);
66-
67-
if ($done >= $total) {
68-
print PHP_EOL;
69-
}
70-
}
7160
}

src/Detector/Strategy/AbstractStrategy.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ public function setConfig(StrategyConfiguration $config): void
4949

5050
abstract public function processFile(string $file, CodeCloneMap $result): void;
5151

52-
public function postProcess(): void
52+
public function postProcess(bool $useProgressBar): void
5353
{
5454
}
5555
}

src/Detector/Strategy/SuffixTreeStrategy.php

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Systemsdk\PhpCPD\Detector\Strategy\SuffixTree\ApproximateCloneDetectingSuffixTree;
1212
use Systemsdk\PhpCPD\Detector\Strategy\SuffixTree\Sentinel;
1313
use Systemsdk\PhpCPD\Detector\Strategy\SuffixTree\Token;
14+
use Systemsdk\PhpCPD\Detector\Traits\ProgressBarTrait;
1415
use Systemsdk\PhpCPD\Exceptions\MissingResultException;
1516

1617
use function array_key_exists;
@@ -33,6 +34,12 @@
3334
*/
3435
final class SuffixTreeStrategy extends AbstractStrategy
3536
{
37+
use ProgressBarTrait;
38+
39+
private const string PROGRESS_BAR_SEARCH_CLONES_TITLE = 'Search for clones';
40+
private const string PROGRESS_BAR_PROCESS_CLONES_TITLE = 'Clones processing';
41+
private const string PROGRESS_BAR_POST_PROCESS_DONE_TITLE = 'Post process done';
42+
3643
/**
3744
* @var array<int, AbstractToken>
3845
*/
@@ -98,12 +105,18 @@ public function processFile(string $file, CodeCloneMap $result): void
98105
/**
99106
* @throws MissingResultException
100107
*/
101-
public function postProcess(): void
108+
public function postProcess(bool $useProgressBar): void
102109
{
103110
if (empty($this->result)) {
104111
throw new MissingResultException('Missing result');
105112
}
106113

114+
$totalSteps = 2;
115+
116+
if ($useProgressBar) {
117+
$this->progressBar(0, $totalSteps, self::PROGRESS_BAR_SEARCH_CLONES_TITLE);
118+
}
119+
107120
// Sentinel = End of word
108121
$this->word[] = new Sentinel();
109122

@@ -113,6 +126,10 @@ public function postProcess(): void
113126
$this->config->headEquality()
114127
);
115128

129+
if ($useProgressBar) {
130+
$this->progressBar(1, $totalSteps, self::PROGRESS_BAR_PROCESS_CLONES_TITLE);
131+
}
132+
116133
foreach ($cloneInfos as $cloneInfo) {
117134
/** @var int[] $others */
118135
$others = $cloneInfo->otherClones->extractFirstList();
@@ -126,6 +143,7 @@ public function postProcess(): void
126143
$otherCloneLength = $this->processCloneLength($cloneLength, $otherToken->file);
127144
$otherLastToken = $this->getLastToken($others[$j], $otherCloneLength);
128145

146+
/** @phpstan-ignore method.nonObject */
129147
$this->result->add(
130148
new CodeClone(
131149
new CodeCloneFile(
@@ -141,6 +159,10 @@ public function postProcess(): void
141159
}
142160
}
143161
}
162+
163+
if ($useProgressBar) {
164+
$this->progressBar(2, $totalSteps, self::PROGRESS_BAR_POST_PROCESS_DONE_TITLE);
165+
}
144166
}
145167

146168
private function processCloneLength(int $cloneLength, string $file): int
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Systemsdk\PhpCPD\Detector\Traits;
6+
7+
use function sprintf;
8+
9+
trait ProgressBarTrait
10+
{
11+
private function progressBar(int $done, int $total, string $title = '', int $width = 30): void
12+
{
13+
$perc = $this->countProgressBarPercent($done, $total);
14+
$bar = (int)floor(($width * $perc) / 100);
15+
print sprintf(
16+
" %s/%s [%s>%s] %s%% %s\r",
17+
$done,
18+
$total,
19+
str_repeat('=', $bar),
20+
str_repeat(' ', $width - $bar),
21+
$perc,
22+
$title
23+
);
24+
25+
if ($done >= $total) {
26+
print PHP_EOL;
27+
}
28+
}
29+
30+
private function countProgressBarPercent(int $done, int $total): int
31+
{
32+
return (int)floor(($done * 100) / $total);
33+
}
34+
}

0 commit comments

Comments
 (0)