Skip to content

Commit 22a2627

Browse files
committed
Sync the package version when synchronizing an entire project
1 parent 6e39696 commit 22a2627

File tree

6 files changed

+154
-6
lines changed

6 files changed

+154
-6
lines changed

ts/WoltLabSuite/Core/Acp/Ui/Devtools/Project/Sync.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { AjaxCallbackSetup, AjaxResponseException } from "../../../../Ajax/Data"
44
import { DialogCallbackSetup } from "../../../../Ui/Dialog/Data";
55
import { dialogFactory } from "../../../../Component/Dialog";
66
import { showDefaultSuccessSnackbar } from "WoltLabSuite/Core/Component/Snackbar";
7+
import { syncVersion } from "WoltLabSuite/Core/Api/DevtoolsProjects/SyncVersion";
78

89
interface PipData {
910
dependencies: string[];
@@ -37,6 +38,7 @@ class AcpUiDevtoolsProjectSync {
3738
private readonly pips: PipData[] = [];
3839
private readonly projectId: number;
3940
private queue: PendingPip[] = [];
41+
#syncVersionAfterCompletion = false;
4042

4143
constructor(projectId: number) {
4244
this.projectId = projectId;
@@ -162,6 +164,7 @@ class AcpUiDevtoolsProjectSync {
162164
}
163165

164166
this.buttonSyncAll.classList.add("disabled");
167+
this.#syncVersionAfterCompletion = true;
165168

166169
this.queue = [];
167170
this.pips.forEach((pip) => {
@@ -174,9 +177,23 @@ class AcpUiDevtoolsProjectSync {
174177

175178
private syncNext(): void {
176179
if (this.queue.length === 0) {
177-
this.buttonSyncAll.classList.remove("disabled");
178-
179-
showDefaultSuccessSnackbar();
180+
const showSuccess = () => {
181+
this.buttonSyncAll.classList.remove("disabled");
182+
183+
showDefaultSuccessSnackbar();
184+
};
185+
186+
if (this.#syncVersionAfterCompletion) {
187+
void this.#syncPackageVersion()
188+
.then(() => {
189+
showSuccess();
190+
})
191+
.finally(() => {
192+
this.#syncVersionAfterCompletion = false;
193+
});
194+
} else {
195+
showSuccess();
196+
}
180197

181198
return;
182199
}
@@ -189,6 +206,10 @@ class AcpUiDevtoolsProjectSync {
189206
return `${pluginName}-${target}`;
190207
}
191208

209+
async #syncPackageVersion(): Promise<void> {
210+
await syncVersion(this.projectId);
211+
}
212+
192213
_ajaxSuccess(data: AjaxResponse): void {
193214
const identifier = this.getButtonIdentifier(data.returnValues.pluginName, data.returnValues.target);
194215
this.buttons.get(identifier)!.disabled = false;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/**
2+
* Synchronizes the version of an installed package with the versio number in
3+
* the `package.xml` of the project.
4+
*
5+
* @author Alexander Ebert
6+
* @copyright 2001-2025 WoltLab GmbH
7+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
8+
* @since 6.2
9+
* @woltlabExcludeBundle all
10+
*/
11+
12+
import { prepareRequest } from "WoltLabSuite/Core/Ajax/Backend";
13+
import { fromInfallibleApiRequest } from "../Result";
14+
15+
export async function syncVersion(projectId: number): Promise<[]> {
16+
return fromInfallibleApiRequest(() => {
17+
return prepareRequest(`${window.WSC_RPC_API_URL}core/devtools-projects/${projectId}/sync-version`).post().fetchAsJson();
18+
});
19+
}

wcfsetup/install/files/js/WoltLabSuite/Core/Acp/Ui/Devtools/Project/Sync.js

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

wcfsetup/install/files/js/WoltLabSuite/Core/Api/DevtoolsProjects/SyncVersion.js

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

wcfsetup/install/files/lib/bootstrap/com.woltlab.wcf.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static function (\wcf\event\endpoint\ControllerCollecting $event) {
152152
$event->register(new \wcf\system\endpoint\controller\core\comments\responses\RenderResponse());
153153
$event->register(new \wcf\system\endpoint\controller\core\comments\responses\RenderResponses());
154154
$event->register(new \wcf\system\endpoint\controller\core\comments\responses\UpdateResponse());
155+
$event->register(new \wcf\system\endpoint\controller\core\devtoolsProjects\SyncVersion());
155156
$event->register(new \wcf\system\endpoint\controller\core\exceptions\RenderException());
156157
$event->register(new \wcf\system\endpoint\controller\core\gridViews\GetRows());
157158
$event->register(new \wcf\system\endpoint\controller\core\gridViews\GetGridView());
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<?php
2+
3+
namespace wcf\system\endpoint\controller\core\devtoolsProjects;
4+
5+
use Laminas\Diactoros\Response\JsonResponse;
6+
use Psr\Http\Message\ResponseInterface;
7+
use Psr\Http\Message\ServerRequestInterface;
8+
use wcf\data\devtools\project\DevtoolsProject;
9+
use wcf\data\package\Package;
10+
use wcf\data\package\PackageEditor;
11+
use wcf\http\Helper;
12+
use wcf\system\cache\builder\PackageCacheBuilder;
13+
use wcf\system\endpoint\IController;
14+
use wcf\system\endpoint\PostRequest;
15+
use wcf\system\exception\PermissionDeniedException;
16+
use wcf\system\exception\UserInputException;
17+
use wcf\system\WCF;
18+
19+
/**
20+
* Syncs the version of the installed package with the one provided by the
21+
* package.xml in the project.
22+
*
23+
* @author Alexander Ebert
24+
* @copyright 2001-2025 WoltLab GmbH
25+
* @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
26+
* @since 6.2
27+
*/
28+
#[PostRequest('/core/devtools-projects/{id:\d+}/sync-version')]
29+
final class SyncVersion implements IController
30+
{
31+
#[\Override]
32+
public function __invoke(ServerRequestInterface $request, array $variables): ResponseInterface
33+
{
34+
$project = Helper::fetchObjectFromRequestParameter($variables['id'], DevtoolsProject::class);
35+
36+
$this->assertProjectCanBeManaged();
37+
38+
$package = $project->getPackage();
39+
if ($package === null) {
40+
throw new UserInputException('projectID');
41+
}
42+
43+
$this->syncVersion($project, $package);
44+
45+
return new JsonResponse([]);
46+
}
47+
48+
private function syncVersion(DevtoolsProject $project, Package $package): void
49+
{
50+
$projectVersion = $project->getPackageArchive()->getPackageInfo('version');
51+
if (Package::compareVersion($package->packageVersion, $projectVersion, '>=')) {
52+
return;
53+
}
54+
55+
(new PackageEditor($package))->update([
56+
'packageVersion' => $projectVersion,
57+
]);
58+
59+
PackageCacheBuilder::getInstance()->reset();
60+
}
61+
62+
private function assertProjectCanBeManaged(): void
63+
{
64+
if (!ENABLE_DEVELOPER_TOOLS || !WCF::getSession()->getPermission('admin.configuration.package.canInstallPackage')) {
65+
throw new PermissionDeniedException();
66+
}
67+
}
68+
}

0 commit comments

Comments
 (0)