• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

cweagans / composer-patches / 4110992550

pending completion
4110992550

Pull #447

github

GitHub
Merge eaa8ee760 into a4b573156
Pull Request #447: 2.x WIP (don't merge yet)

457 of 457 new or added lines in 28 files covered. (100.0%)

456 of 570 relevant lines covered (80.0%)

3.29 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

59.46
/src/Locker.php
1
<?php
2

3
namespace cweagans\Composer;
4

5
// Much of this file was taken directly from Composer's locker.
6

7
use Composer\Json\JsonFile;
8
use LogicException;
9
use Seld\JsonLint\ParsingException;
10

11
class Locker
12
{
13
    protected JsonFile $lockFile;
14

15
    protected bool $virtualFileWritten = false;
16

17
    protected ?array $lockDataCache = null;
18

19
    protected string $hash;
20

21
    public function __construct(JsonFile $lockFile)
22
    {
23
        $this->lockFile = $lockFile;
9✔
24
    }
25

26
    /**
27
     * Returns the sha256 hash of the sorted content of the patches.lock file.
28
     *
29
     * @param PatchCollection $patchCollection
30
     *   The resolved patches for the project.
31
     */
32
    public static function getCollectionHash(PatchCollection $patchCollection): string
33
    {
34
        $file = $patchCollection->jsonSerialize();
8✔
35
        ksort($file);
8✔
36
        return hash('sha256', JsonFile::encode($file, 0));
8✔
37
    }
38

39
    public function isLocked(): bool
40
    {
41
        if (!$this->virtualFileWritten && !$this->lockFile->exists()) {
8✔
42
            return false;
8✔
43
        }
44

45
        try {
46
            $data = $this->getLockData();
1✔
47
            return isset($data['patches']);
1✔
48
        } catch (LogicException $e) {
×
49
            return false;
×
50
        }
51
    }
52

53
    public function isFresh(PatchCollection $patchCollection): bool
54
    {
55
        try {
56
            $lock = $this->getLockData();
×
57
        } catch (LogicException $e) {
×
58
            return false;
×
59
        }
60

61
        if (empty($lock['patches']) || empty($lock['_hash'])) {
×
62
            return false;
×
63
        }
64

65
        $expectedHash = self::getCollectionHash($patchCollection);
×
66

67
        return $expectedHash === $lock['_hash'];
×
68
    }
69

70
    public function getLockData(): array
71
    {
72
        if (!is_null($this->lockDataCache)) {
1✔
73
            return $this->lockDataCache;
1✔
74
        }
75

76
        if (!$this->lockFile->exists()) {
1✔
77
            throw new LogicException('No lockfile found. Unable to read locked patches.');
×
78
        }
79

80
        return $this->lockDataCache = $this->lockFile->read();
1✔
81
    }
82

83
    public function setLockData(PatchCollection $patchCollection, bool $write = true): bool
84
    {
85
        $lock = $patchCollection->jsonSerialize();
8✔
86
        $lock['_hash'] = self::getCollectionHash($patchCollection);
8✔
87
        ksort($lock);
8✔
88

89
        try {
90
            $isLocked = $this->isLocked();
8✔
91
        } catch (ParsingException $e) {
×
92
            $isLocked = false;
×
93
        }
94
        if (!$isLocked || $lock !== $this->getLockData()) {
8✔
95
            if ($write) {
8✔
96
                $this->lockFile->write($lock);
8✔
97
                $this->lockDataCache = null;
8✔
98
                $this->virtualFileWritten = false;
8✔
99
            } else {
100
                $this->virtualFileWritten = true;
×
101
                $this->lockDataCache = JsonFile::parseJson(JsonFile::encode($lock));
×
102
            }
103

104
            return true;
8✔
105
        }
106

107
        return false;
×
108
    }
109
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc