-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathinstall.php
More file actions
executable file
·187 lines (163 loc) · 8.6 KB
/
Copy pathinstall.php
File metadata and controls
executable file
·187 lines (163 loc) · 8.6 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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
<?php
use Pushword\Core\PushwordCoreBundle;
use Pushword\Installer\PostInstall;
use Pushword\Installer\SystemCheck;
/**
* Execute via Pushword\Installer\PostInstall::postUpdateCommand.
*/
if (! PostInstall::isRoot()) {
throw new Exception('installer mus be run from root');
}
PostInstall::remove([
'templates/base.html.twig',
'config/packages/security.yaml',
'config/packages/doctrine.yaml',
'config/packages/vich_uploader.yaml',
// doctrine/doctrine-bundle's recipe writes a PostgreSQL service, and symfony/mailer
// adds a Mailpit one to the override — a stack with no application service, for a
// database Pushword does not use. `pw:docker:init` writes the real thing.
'compose.yaml',
'compose.override.yaml',
]);
// Set pushword bundle first to avoid errors. Every other bundle appends itself from its
// own install.php, so core cannot use PostInstall::registerBundle() here: it needs the
// head of the list, not the tail.
PostInstall::replace('config/bundles.php', PushwordCoreBundle::class."::class => ['all' => true],", '');
PostInstall::replace('config/bundles.php', 'return [', 'return [
'.PushwordCoreBundle::class."::class => ['all' => true],");
// echo '~~ Copy Entities in ./src/Entity'.chr(10);
// PostInstall::mirror('vendor/pushword/dev-app/src/Entity', 'src/Entity');
// The starter content, not dev-app's fixtures: those are the test suite's rig, they
// reference pages and bundles a fresh install does not have.
@unlink('src/DataFixtures/AppFixtures.php');
PostInstall::mirror('vendor/pushword/core/starter', 'src/DataFixtures');
// At the end: the catch-all page route must come after every other bundle's.
echo '~~ Adding Puswhord Routes'.chr(10);
PostInstall::insertIn(
'config/routes.yaml',
"\npushword:\n resource: '@PushwordCoreBundle/Resources/config/routes.yaml'\n",
PostInstall::INSERT_AT_END
);
echo '~~ Create database'.chr(10);
// if it's a default symfony installation, switch from postgresql to sqlite
PostInstall::replace('.env', 'postgresql://app:!ChangeMe!@127.0.0.1:5432/app?serverVersion=16&charset=utf8', 'sqlite:///%kernel.project_dir%/var/app.db');
// and define an APP_SECRET
PostInstall::replace('.env', "APP_SECRET=\n", 'APP_SECRET='.sha1(md5(uniqid())).chr(10));
// dev-app's media doubles as the test suite's fixtures: take the demo photos, leave the
// branding and the PDF test artifact behind.
PostInstall::mirror('vendor/pushword/dev-app/media~', 'media');
PostInstall::remove(['media/piedweb-logo.png', 'media/logo.svg', 'media/test.pdf']);
$freshInstall = ! file_exists('var/app.db');
$commands = 'php bin/console doctrine:schema:update --force -q';
if ($freshInstall) {
$commands .= ' && php bin/console doctrine:fixtures:load --no-interaction -q';
}
$commands .= ' && php bin/console pw:image:cache -q';
echo '~~ Symlinking assets'.chr(10);
$commands .= ' && php bin/console assets:install --symlink --relative -q';
exec($commands);
PostInstall::dumpFile('public/build/manifest.json', '{}');
if ($freshInstall) {
// Asking beats seeding a password that ships in the documentation — but only when
// someone is there to answer. Run from CI, a script or `composer --no-interaction`,
// this falls back to the demo account so the install still completes unattended.
$userCreated = false;
if (PostInstall::isInteractive()) {
echo '~~ Create the account you will log in with:'.chr(10);
// No arguments: the command asks for each one, and already defaults the role
// to ROLE_SUPER_ADMIN.
passthru('php bin/console pw:user:create', $status);
$userCreated = 0 === $status;
}
if (! $userCreated) {
exec('php bin/console pw:user:create admin@example.tld p@ssword ROLE_SUPER_ADMIN -q');
echo '~~ Super admin created: admin@example.tld / p@ssword'.chr(10);
echo '~~ Log in on /admin and change these credentials.'.chr(10);
}
}
echo '~~ Copy assets file in ./assets'.chr(10);
PostInstall::remove(['package.json', 'webpack.config.js', 'assets']);
PostInstall::mirror('vendor/pushword/dev-app/assets', 'assets');
PostInstall::copy('vendor/pushword/dev-app/vite.config.js', 'vite.config.js');
PostInstall::copy('vendor/pushword/dev-app/package.json', 'package.json');
PostInstall::copy('vendor/pushword/dev-app/Caddyfile', 'Caddyfile');
$defaultConfig = 'pushword:'.chr(10)
.' # Documention'.chr(10)
.' # https://pushword.piedweb.com/installation'.chr(10)
.' # Example'.chr(10)
.' # https://github.com/Pushword/Pushword/blob/main/packages/dev-app/config/packages/pushword.php'.chr(10);
PostInstall::dumpFile('config/packages/pushword.yaml', $defaultConfig);
// pushword/new ships AGENTS.md; Claude Code reads CLAUDE.md. Symlink one to the other,
// as the monorepo does, so both agents get the same file. Composer's zip extraction does
// not preserve symlinks, hence creating it here rather than shipping it.
if (file_exists('AGENTS.md') && ! file_exists('CLAUDE.md')) {
symlink('AGENTS.md', 'CLAUDE.md');
}
// Install phpstan
// ---------------
PostInstall::copy('vendor/pushword/dev-app/phpstan.dist.neon', 'phpstan.dist.neon');
PostInstall::copy('vendor/pushword/dev-app/bin/console-test.php', 'bin/console-test.php');
PostInstall::replace('bin/console-test.php', "'/../../../vendor/autoload.php'", "'/../vendor/autoload.php'");
PostInstall::copy('vendor/pushword/dev-app/bin/object-test.php', 'bin/object-test.php');
PostInstall::replace('bin/object-test.php', "'/../../../vendor/autoload.php'", "'/../vendor/autoload.php'");
// À tester si appeler composer depuis composer ne fout pas le bordel
exec('composer config --no-plugins allow-plugins.phpstan/extension-installer true');
exec('composer config --no-plugins scripts.stan "vendor/bin/phpstan"');
if (! file_exists('vendor/phpstan/phpstan/phpstan.phar')) {
exec('composer require --dev phpstan/extension-installer:* phpstan/phpstan:* phpstan/phpstan-doctrine:* phpstan/phpstan-phpunit:* phpstan/phpstan-strict-rules:* phpstan/phpstan-symfony:*');
}
// Install php-cs-fixer
// -------------------
PostInstall::copy('vendor/pushword/dev-app/php-cs-fixer.dist.php.template', '.php-cs-fixer.dist.php');
exec('composer config --no-plugins scripts.format "vendor/bin/php-cs-fixer fix"');
if (! file_exists('vendor/friendsofphp/php-cs-fixer/php-cs-fixer')) {
exec('composer require --no-plugins --dev friendsofphp/php-cs-fixer:*');
}
// Install RECTOR
// -------------------
// Rector is a bit too expensive on a cheap VPS with 4Gb of RAM
/*
cp vendor/pushword/dev-app/rector.php rector.php && \
cp vendor/pushword/dev-app/tests/symfonyContainer.php tests/symfonyContainer.php && \
composer config --no-plugins scripts.rector "vendor/bin/rector process && composer format" && \
composer require --no-plugins --dev rector/rector:*
*/
// PostInstall::copy('vendor/pushword/dev-app/rector.php', 'rector.php');
// PostInstall::copy('vendor/pushword/dev-app/tests/symfonyContainer.php', 'tests/symfonyContainer.php');
// exec('composer config --no-plugins scripts.rector "vendor/bin/rector process && composer format"');
// exec('composer require --no-plugins --dev rector/rector:*');
PostInstall::replace('.gitignore', '/var/', '/var/*');
PostInstall::insertIn('.gitignore', '###> pushword ###
public/assets
public/media
public/sw.js
static/
!/var/installer/
###< pushword ###
', PostInstall::INSERT_AT_END);
// Docker
// ------
// Offered last, so the answer is the last thing on screen, and offered only when it is
// a real choice: no Docker daemon, no question and no Dockerfile left lying around.
// The recommendation follows the machine — a PHP that already has what Pushword needs
// is better off without a layer in between; one that does not is better off with the
// image, which ships them.
$systemCheck = SystemCheck::probe();
if (! $systemCheck->shouldAsk()) {
if ($systemCheck->recommendsDocker()) {
echo '⚠ Pushword needs '.implode(', ', $systemCheck->missing).', which this PHP does not have.'.chr(10);
echo '⚠ Install them (see https://pushword.piedweb.com/installation), or install'.chr(10);
echo '⚠ Docker and run `php bin/console pw:docker:init`.'.chr(10);
}
} elseif (PostInstall::isInteractive()) {
$dockerRecommended = $systemCheck->recommendsDocker();
echo chr(10).'~~ Docker is available here. '.ucfirst($systemCheck->reason()).'.'.chr(10);
if (PostInstall::confirm(
'~~ Run Pushword in Docker? '.($dockerRecommended ? '[Yes (recommended) / no]' : '[yes / No (recommended)]').': ',
$dockerRecommended
)) {
passthru('php bin/console pw:docker:init');
} else {
echo '~~ No Docker file written. `php bin/console pw:docker:init` adds them later.'.chr(10);
}
}