forked from tempestphp/tempest-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathComposer.php
More file actions
118 lines (88 loc) · 2.98 KB
/
Composer.php
File metadata and controls
118 lines (88 loc) · 2.98 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
declare(strict_types=1);
namespace Tempest\Core;
use Tempest\Process\ProcessExecutor;
use Tempest\Support\Arr;
use Tempest\Support\Filesystem;
use Tempest\Support\Namespace\Psr4Namespace;
use Tempest\Support\Path;
use Tempest\Support\Str;
use function Tempest\Support\arr;
final class Composer
{
/** @var array<Psr4Namespace> */
public array $namespaces;
public ?Psr4Namespace $mainNamespace = null;
private string $composerPath;
private array $composer;
public function __construct(
private readonly string $root,
private ProcessExecutor $executor,
) {}
public function load(): self
{
$this->composerPath = Path\normalize($this->root, 'composer.json');
$this->composer = $this->loadComposerFile($this->composerPath);
$this->namespaces = arr($this->composer)
->get('autoload.psr-4', default: arr())
->map(fn (string $path, string $namespace) => new Psr4Namespace($namespace, $path))
->sortByCallback(fn (Psr4Namespace $ns1, Psr4Namespace $ns2) => strlen($ns1->path) <=> strlen($ns2->path))
->values()
->toArray();
foreach ($this->namespaces as $namespace) {
if (Str\starts_with(Str\ensure_ends_with($namespace->path, '/'), ['app/', 'src/', 'source/', 'lib/'])) {
$this->mainNamespace = $namespace;
break;
}
}
if (! isset($this->mainNamespace) && count($this->namespaces)) {
$this->mainNamespace = $this->namespaces[0];
}
$this->namespaces = arr([
$this->mainNamespace,
...$this->namespaces,
])
->filter()
->unique(fn (Psr4Namespace $ns) => $ns->namespace)
->toArray();
return $this;
}
public function setMainNamespace(Psr4Namespace $namespace): self
{
$this->mainNamespace = $namespace;
return $this;
}
public function setNamespaces(Psr4Namespace|array $namespaces): self
{
$this->namespaces = Arr\wrap($namespaces);
return $this;
}
public function setProcessExecutor(ProcessExecutor $executor): self
{
$this->executor = $executor;
return $this;
}
public function addNamespace(string $namespace, string $path): self
{
$path = str_replace($this->root, '.', $path);
$this->composer['autoload']['psr-4'][$namespace] = $path;
return $this;
}
public function save(): self
{
Filesystem\write_json($this->composerPath, $this->composer, pretty: true);
return $this;
}
public function executeUpdate(): self
{
$this->executor->run('composer up');
return $this;
}
private function loadComposerFile(string $path): array
{
if (! Filesystem\is_file($path)) {
throw new ComposerJsonCouldNotBeLocated('Could not locate composer.json.');
}
return Filesystem\read_json($path);
}
}