1
0
mirror of https://github.com/flarum/core.git synced 2025-08-06 00:17:31 +02:00

fix(package-manager): bugs

This commit is contained in:
Sami Mazouz
2024-01-06 18:00:09 +01:00
parent 7fb0e08c0a
commit 56b2b3b2bc
11 changed files with 88 additions and 29 deletions

View File

@@ -64,12 +64,12 @@ export default class AuthMethodModal<CustomAttrs extends IAuthMethodModalAttrs =
oninput={(e: InputEvent) => this.token((e.target as HTMLTextAreaElement).value)} oninput={(e: InputEvent) => this.token((e.target as HTMLTextAreaElement).value)}
rows="6" rows="6"
placeholder={ placeholder={
this.token() === '***' this.token().startsWith('unchanged:')
? extractText(app.translator.trans('flarum-package-manager.admin.auth_config.add_modal.unchanged_token_placeholder')) ? extractText(app.translator.trans('flarum-package-manager.admin.auth_config.add_modal.unchanged_token_placeholder'))
: '' : ''
} }
> >
{this.token() === '***' ? '' : this.token()} {this.token().startsWith('unchanged:') ? '' : this.token()}
</textarea> </textarea>
</div> </div>
<div className="Form-group"> <div className="Form-group">

View File

@@ -18,10 +18,17 @@ export default class ConfigureAuth extends ConfigureJson<IConfigureJson> {
content(): Mithril.Children { content(): Mithril.Children {
const authSettings = Object.keys(this.settings); const authSettings = Object.keys(this.settings);
const hasAuthSettings =
authSettings.length &&
authSettings.every((type) => {
const data = this.settings[type]();
return Array.isArray(data) ? data.length : Object.keys(data).length;
});
return ( return (
<div className="SettingsGroups-content"> <div className="SettingsGroups-content">
{authSettings.length ? ( {hasAuthSettings ? (
authSettings.map((type) => { authSettings.map((type) => {
const hosts = this.settings[type](); const hosts = this.settings[type]();
@@ -42,7 +49,7 @@ export default class ConfigureAuth extends ConfigureJson<IConfigureJson> {
type, type,
host, host,
token: data, token: data,
onsubmit: this.onchange.bind(this), onsubmit: this.onchange.bind(this, host),
}) })
} }
> >
@@ -88,7 +95,7 @@ export default class ConfigureAuth extends ConfigureJson<IConfigureJson> {
loading={this.loading} loading={this.loading}
onclick={() => onclick={() =>
app.modal.show(AuthMethodModal, { app.modal.show(AuthMethodModal, {
onsubmit: this.onchange.bind(this), onsubmit: this.onchange.bind(this, null),
}) })
} }
> >
@@ -99,7 +106,15 @@ export default class ConfigureAuth extends ConfigureJson<IConfigureJson> {
return items; return items;
} }
onchange(type: string, host: string, token: string) { onchange(oldHost: string | null, type: string, host: string, token: string) {
this.setting(type)({ ...this.setting(type)(), [host]: token }); const data = { ...this.setting(type)() };
if (oldHost) {
delete data[oldHost];
}
data[host] = token;
this.setting(type)(data);
} }
} }

View File

@@ -59,7 +59,14 @@ export default class ConfigureComposer extends ConfigureJson<IConfigureJson> {
app.modal.show(RepositoryModal, { app.modal.show(RepositoryModal, {
name, name,
repository, repository,
onsubmit: this.onchange.bind(this), onsubmit: (repository: Repository, newName: string) => {
const repositories = this.setting('repositories')();
delete repositories[name];
this.setting('repositories')(repositories);
this.onchange(repository, newName);
},
}) })
} }
> >

View File

@@ -15,7 +15,7 @@ export default class Pagination extends Component<PaginationAttrs> {
return ( return (
<nav className="Pagination UserListPage-gridPagination"> <nav className="Pagination UserListPage-gridPagination">
<Button <Button
disabled={!this.attrs.list.hasPrev()} disabled={!this.attrs.list.hasPrev() || app.packageManager.control.isLoading()}
title={app.translator.trans('core.admin.users.pagination.back_button')} title={app.translator.trans('core.admin.users.pagination.back_button')}
onclick={() => this.attrs.list.prev()} onclick={() => this.attrs.list.prev()}
icon="fas fa-chevron-left" icon="fas fa-chevron-left"
@@ -28,7 +28,7 @@ export default class Pagination extends Component<PaginationAttrs> {
})} })}
</span> </span>
<Button <Button
disabled={!this.attrs.list.hasNext()} disabled={!this.attrs.list.hasNext() || app.packageManager.control.isLoading()}
title={app.translator.trans('core.admin.users.pagination.next_button')} title={app.translator.trans('core.admin.users.pagination.next_button')}
onclick={() => this.attrs.list.next()} onclick={() => this.attrs.list.next()}
icon="fas fa-chevron-right" icon="fas fa-chevron-right"

View File

@@ -39,6 +39,7 @@ export default class QueueSection extends Component<{}> {
icon="fas fa-sync-alt" icon="fas fa-sync-alt"
onclick={() => app.packageManager.queue.load()} onclick={() => app.packageManager.queue.load()}
aria-label={app.translator.trans('flarum-package-manager.admin.sections.queue.refresh')} aria-label={app.translator.trans('flarum-package-manager.admin.sections.queue.refresh')}
disabled={app.packageManager.control.isLoading()}
/> />
</div> </div>
</div> </div>
@@ -147,6 +148,7 @@ export default class QueueSection extends Component<{}> {
// @todo fix in core // @todo fix in core
// @ts-ignore // @ts-ignore
onclick={() => app.modal.show(TaskOutputModal, { task })} onclick={() => app.modal.show(TaskOutputModal, { task })}
disabled={['pending', 'running'].includes(task.status())}
/> />
), ),
className: 'Table-controls', className: 'Table-controls',

View File

@@ -19,14 +19,16 @@ export default class TaskOutputModal<CustomAttrs extends TaskOutputModalAttrs =
return ( return (
<div className="Modal-body"> <div className="Modal-body">
<div className="TaskOutputModal-data"> <div className="TaskOutputModal-data">
<div className="Form-group"> {this.attrs.task.status() === 'failure' && (
<label>{app.translator.trans('flarum-package-manager.admin.sections.queue.output_modal.guessed_cause')}</label> <div className="Form-group">
<div className="FormControl TaskOutputModal-data-guessed-cause"> <label>{app.translator.trans('flarum-package-manager.admin.sections.queue.output_modal.guessed_cause')}</label>
{(this.attrs.task.guessedCause() && <div className="FormControl TaskOutputModal-data-guessed-cause">
app.translator.trans('flarum-package-manager.admin.exceptions.guessed_cause.' + this.attrs.task.guessedCause())) || {(this.attrs.task.guessedCause() &&
app.translator.trans('flarum-package-manager.admin.sections.queue.output_modal.cause_unknown')} app.translator.trans('flarum-package-manager.admin.exceptions.guessed_cause.' + this.attrs.task.guessedCause())) ||
app.translator.trans('flarum-package-manager.admin.sections.queue.output_modal.cause_unknown')}
</div>
</div> </div>
</div> )}
<div className="Form-group"> <div className="Form-group">
<label>{app.translator.trans('flarum-package-manager.admin.sections.queue.output_modal.command')}</label> <label>{app.translator.trans('flarum-package-manager.admin.sections.queue.output_modal.command')}</label>

View File

@@ -36,6 +36,8 @@ export default class QueueState {
// Refresh the page // Refresh the page
window.location.reload(); window.location.reload();
} else if (app.packageManager.control.isLoading()) {
app.packageManager.control.setLoading(null);
} }
return data; return data;

View File

@@ -16,6 +16,7 @@ use Flarum\PackageManager\ConfigureComposerValidator;
use Illuminate\Contracts\Filesystem\FileNotFoundException; use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Filesystem\Filesystem; use Illuminate\Filesystem\Filesystem;
use Illuminate\Support\Arr; use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Laminas\Diactoros\Response\JsonResponse; use Laminas\Diactoros\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Message\ServerRequestInterface;
@@ -102,6 +103,14 @@ class ConfigureComposerController implements RequestHandlerInterface
$this->composerJson->set($composerJson); $this->composerJson->set($composerJson);
} }
$default = [
'minimum-stability' => 'stable',
];
foreach ($this->configurable as $key) {
$composerJson[$key] = Arr::get($composerJson, $key, Arr::get($default, $key));
}
return Arr::only($composerJson, $this->configurable); return Arr::only($composerJson, $this->configurable);
} }
@@ -125,9 +134,23 @@ class ConfigureComposerController implements RequestHandlerInterface
continue; continue;
} }
$data[$type][$host] = $token === '***' if (str_starts_with($token, 'unchanged:')) {
? $authJson[$type][$host] $old = Str::of($token)->explode(':')->skip(1)->values()->all();
: $token;
if (count($old) !== 2) {
continue;
}
[$oldType, $oldHost] = $old;
if (! isset($authJson[$oldType][$oldHost])) {
continue;
}
$data[$type][$host] = $authJson[$oldType][$oldHost];
} else {
$data[$type][$host] = $token;
}
} }
} }
@@ -138,7 +161,7 @@ class ConfigureComposerController implements RequestHandlerInterface
// Remove tokens from response. // Remove tokens from response.
foreach ($authJson as $type => $hosts) { foreach ($authJson as $type => $hosts) {
foreach ($hosts as $host => $token) { foreach ($hosts as $host => $token) {
$authJson[$type][$host] = '***'; $authJson[$type][$host] = "unchanged:$type:$host";
} }
} }

View File

@@ -44,7 +44,7 @@ class ListTasksController extends AbstractListController
$offset = $this->extractOffset($request); $offset = $this->extractOffset($request);
$results = Task::query() $results = Task::query()
->latest() ->latest('id')
->offset($offset) ->offset($offset)
->limit($limit) ->limit($limit)
->get(); ->get();

View File

@@ -38,6 +38,11 @@ class ComposerAdapter
*/ */
private $paths; private $paths;
/**
* @var BufferedOutput|null
*/
private $output = null;
public function __construct(Application $application, OutputLogger $logger, Paths $paths) public function __construct(Application $application, OutputLogger $logger, Paths $paths)
{ {
$this->application = $application; $this->application = $application;
@@ -49,24 +54,27 @@ class ComposerAdapter
{ {
$this->application->resetComposer(); $this->application->resetComposer();
$output = new BufferedOutput(); $this->output = $this->output ?? new BufferedOutput();
// This hack is necessary so that relative path repositories are resolved properly. // This hack is necessary so that relative path repositories are resolved properly.
$currDir = getcwd(); $currDir = getcwd();
chdir($this->paths->base); chdir($this->paths->base);
$exitCode = $this->application->run($input, $output); $exitCode = $this->application->run($input, $this->output);
chdir($currDir); chdir($currDir);
$command = Util::readableConsoleInput($input); $command = Util::readableConsoleInput($input);
$output = $output->fetch(); $outputContent = $this->output->fetch();
if ($task) { if ($task) {
$task->update(compact('command', 'output')); $task->update([
'command' => $command,
'output' => $outputContent,
]);
} else { } else {
$this->logger->log($command, $output, $exitCode); $this->logger->log($command, $outputContent, $exitCode);
} }
return new ComposerOutput($exitCode, $output); return new ComposerOutput($exitCode, $outputContent);
} }
public static function setPhpVersion(string $phpVersion) public static function setPhpVersion(string $phpVersion)

View File

@@ -53,7 +53,7 @@ class ComposerCommandJob extends AbstractJob implements ShouldBeUnique
public function abort(Throwable $exception) public function abort(Throwable $exception)
{ {
if (! $this->command->task->output) { if (empty($this->command->task->output)) {
$this->command->task->output = $exception->getMessage(); $this->command->task->output = $exception->getMessage();
} }