Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions PhpcsChanged/BatchScanResult.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);

namespace PhpcsChanged;

/**
* The phpcs output for a set of files after the batch scan phase, combining
* results served from the cache with those produced by the batched phpcs
* invocation. Consumed by the filter phase of a workflow.
*/
class BatchScanResult {
/**
* @var array<string, string> phpcs output for the modified version, keyed by file
*/
private $modifiedOutputs;

/**
* @var array<string, string> phpcs output for the unmodified version, keyed by file
*/
private $unmodifiedOutputs;

/**
* @var float Wall-clock time attributed to each scanned file
*/
private $timePerFile;

/**
* @param array<string, string> $modifiedOutputs
* @param array<string, string> $unmodifiedOutputs
*/
public function __construct(array $modifiedOutputs, array $unmodifiedOutputs, float $timePerFile) {
$this->modifiedOutputs = $modifiedOutputs;
$this->unmodifiedOutputs = $unmodifiedOutputs;
$this->timePerFile = $timePerFile;
}

public function getModifiedOutput(string $file): string {
return $this->modifiedOutputs[$file] ?? '';
}

public function getUnmodifiedOutput(string $file): string {
return $this->unmodifiedOutputs[$file] ?? '';
}

public function getTimePerFile(): float {
return $this->timePerFile;
}
}
416 changes: 290 additions & 126 deletions PhpcsChanged/Cli.php

Large diffs are not rendered by default.

105 changes: 105 additions & 0 deletions PhpcsChanged/ScanPlan.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php
declare(strict_types=1);

namespace PhpcsChanged;

/**
* Describes, for a set of files, which phpcs scans must still be run and which
* outputs can be served from the cache. Produced by the pre-batch phase of a
* workflow and consumed by the batch and filter phases.
*/
class ScanPlan {
/**
* @var string[] Files whose modified version still needs a phpcs scan
*/
private $needsModifiedPhpcs;

/**
* @var string[] Files whose unmodified version still needs a phpcs scan
*/
private $needsUnmodifiedPhpcs;

/**
* @var array<string, string> Cached phpcs output for the modified version, keyed by file
*/
private $modifiedOutputs;

/**
* @var array<string, string> Cached phpcs output for the unmodified version, keyed by file
*/
private $unmodifiedOutputs;

/**
* @var array<string, bool> Whether each file is new (has no unmodified version), keyed by file
*/
private $isNewFileMap;

/**
* @var array<string, string> Cache key (file hash) for the modified version, keyed by file
*/
private $modifiedHashMap;

/**
* @var array<string, string> Cache key for the unmodified version (svn revision id or git hash), keyed by file
*/
private $unmodifiedCacheKeyMap;

/**
* @param string[] $needsModifiedPhpcs
* @param string[] $needsUnmodifiedPhpcs
* @param array<string, string> $modifiedOutputs
* @param array<string, string> $unmodifiedOutputs
* @param array<string, bool> $isNewFileMap
* @param array<string, string> $modifiedHashMap
* @param array<string, string> $unmodifiedCacheKeyMap
*/
public function __construct(array $needsModifiedPhpcs, array $needsUnmodifiedPhpcs, array $modifiedOutputs, array $unmodifiedOutputs, array $isNewFileMap, array $modifiedHashMap, array $unmodifiedCacheKeyMap) {
$this->needsModifiedPhpcs = $needsModifiedPhpcs;
$this->needsUnmodifiedPhpcs = $needsUnmodifiedPhpcs;
$this->modifiedOutputs = $modifiedOutputs;
$this->unmodifiedOutputs = $unmodifiedOutputs;
$this->isNewFileMap = $isNewFileMap;
$this->modifiedHashMap = $modifiedHashMap;
$this->unmodifiedCacheKeyMap = $unmodifiedCacheKeyMap;
}

/**
* @return string[]
*/
public function getNeedsModifiedPhpcs(): array {
return $this->needsModifiedPhpcs;
}

/**
* @return string[]
*/
public function getNeedsUnmodifiedPhpcs(): array {
return $this->needsUnmodifiedPhpcs;
}

/**
* @return array<string, string>
*/
public function getModifiedOutputs(): array {
return $this->modifiedOutputs;
}

/**
* @return array<string, string>
*/
public function getUnmodifiedOutputs(): array {
return $this->unmodifiedOutputs;
}

public function isNewFile(string $file): bool {
return $this->isNewFileMap[$file] ?? false;
}

public function getModifiedCacheKey(string $file): string {
return $this->modifiedHashMap[$file] ?? '';
}

public function getUnmodifiedCacheKey(string $file): string {
return $this->unmodifiedCacheKeyMap[$file] ?? '';
}
}
30 changes: 22 additions & 8 deletions PhpcsChanged/ShellOperator.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,33 @@ public function getGitHashOfModifiedFile(string $fileName): string;

public function getGitHashOfUnmodifiedFile(string $fileName): string;

public function getPhpcsOutputOfModifiedGitFile(string $fileName): string;

public function getPhpcsOutputOfUnmodifiedGitFile(string $fileName): string;

public function getPhpcsOutputOfModifiedSvnFile(string $fileName): string;

public function getPhpcsOutputOfUnmodifiedSvnFile(string $fileName): string;

public function getGitUnifiedDiff(string $fileName): string;

public function getGitMergeBase(): string;

public function getSvnRevisionId(string $fileName): string;

public function getSvnUnifiedDiff(string $fileName): string;

/**
* Run phpcs once on all modified and unmodified versions of the given git files.
* New files should not appear in $unmodifiedFileNames.
*
* @param string[] $modifiedFileNames files needing modified (new) phpcs output
* @param string[] $unmodifiedFileNames files needing unmodified (old) phpcs output
* @return array{new: array<string,string>, old: array<string,string>}
* Each sub-array maps originalPath => single-file phpcs JSON string
*/
public function getPhpcsOutputForGitBatch(array $modifiedFileNames, array $unmodifiedFileNames): array;

/**
* Run phpcs once on all modified and unmodified versions of the given svn files.
* New files should not appear in $unmodifiedFileNames.
*
* @param string[] $modifiedFileNames files needing modified (new) phpcs output
* @param string[] $unmodifiedFileNames files needing unmodified (old) phpcs output
* @return array{new: array<string,string>, old: array<string,string>}
* Each sub-array maps originalPath => single-file phpcs JSON string
*/
public function getPhpcsOutputForSvnBatch(array $modifiedFileNames, array $unmodifiedFileNames): array;
}
11 changes: 11 additions & 0 deletions PhpcsChanged/ShellPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@ interface ShellPlatform {
*/
public function executeCommand(string $command, ?int &$return_val = null): string;

/**
* Run $command and write its stdout to $filePath, preserving the exact bytes.
*
* Unlike executeCommand(), which is line-oriented and normalizes trailing
* newlines, this redirects the command's stdout straight to the file so that
* file content (e.g. from `git show` or `cat`) reaches phpcs byte-for-byte.
*
* @return int The command's exit code.
*/
public function writeCommandOutputToFile(string $command, string $filePath): int;

/**
* Validate that an executable exists and is runnable.
*
Expand Down
Loading
Loading