diff options
| author | Leitwolf11 | 2026-10-29 09:53:57 +0300 |
|---|---|---|
| committer | Leitwolf11 | 2026-10-29 09:53:57 +0300 |
| commit | 58fa0d19d223aaebf9973ebd446c4bb855351ef9 (patch) | |
| tree | 6fce1c3d9f2255e80ec92c3040e7280c0ce131ae /apps/api/ViGet/ViGetCommand.cs | |
| parent | f22418235a0a87bc05b3bf9079fcdefba002d3b2 (diff) | |
| download | progmaweb-58fa0d19d223aaebf9973ebd446c4bb855351ef9.tar.gz | |
Add the Tazel plugin catalog of ViGet to the API
ViGet opens in stages: first only Progmasoft publishes Tazel plugins, later
every account. This adds the catalog and the server-side publishing for the
first stage; nothing publishes through the API yet.
- ViGet/: the catalog of Tazel plugins (in memory, or in PostgreSQL beside
the accounts with its own numbered schema steps), the descriptor read from
the JAR (META-INF/tazel-plugin.properties, with a reader of the Java
properties format, and the ProjectPlugin service entry), and publishing:
the publisher must be in ViGet:TazelPublishers (Progmasoft for now) and an
existing account of that exact name, a version is never replaced, names
that differ only in letter case are refused, and ViGet needs a
description, an author and a license. The JAR is kept at
dslplugins/tazel/<Publisher>/<Name>/<Version>/<Name>-<Version>.jar below
ViGet:ArtifactRoot.
- Read endpoints under /api/v1/viget/dslplugins/tazel: the list, a plugin,
and index.json, the index Tazel reads.
- 'viget publish-tazel-plugin <jar>' and 'viget yank-tazel-plugin' run with
the configuration of the service instead of the service.
- The account store can find an account by name.
The pages, the Nginx routes and the deployment follow.
Diffstat (limited to 'apps/api/ViGet/ViGetCommand.cs')
| -rw-r--r-- | apps/api/ViGet/ViGetCommand.cs | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/apps/api/ViGet/ViGetCommand.cs b/apps/api/ViGet/ViGetCommand.cs new file mode 100644 index 0000000..ad99aee --- /dev/null +++ b/apps/api/ViGet/ViGetCommand.cs @@ -0,0 +1,85 @@ +// SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com> +// SPDX-License-Identifier: AGPL-3.0-or-later WITH AdditionRef-Progmasoft-Patent-Grant-1.1 + +using Npgsql; + +namespace Progmasoft.Progmaweb.Api.ViGet; + +/// <summary> +/// The commands that manage the Tazel plugin catalog on the server, while publishing is not open through the API: +/// <c>viget publish-tazel-plugin <jar></c> and <c>viget yank-tazel-plugin <Publisher> <Name> +/// <Version> [--undo]</c>. They run with the configuration of the service, as its user. +/// </summary> +internal static class ViGetCommand +{ + /// <summary>Whether the arguments of the program ask for a ViGet command rather than the web service.</summary> + public static bool IsCommand(string[] args) => args is ["viget", ..]; + + /// <summary>Runs a ViGet command.</summary> + /// <param name="services">The services of the API, not started.</param> + /// <param name="args">The arguments after <c>viget</c>.</param> + /// <param name="output">Where results go.</param> + /// <param name="errors">Where errors go.</param> + /// <param name="cancellationToken">Cancels the command.</param> + /// <returns>The exit code: 0 on success, 1 when the command was refused, 2 for a wrong command line.</returns> + public static async Task<int> RunAsync( + IServiceProvider services, + string[] args, + TextWriter output, + TextWriter errors, + CancellationToken cancellationToken) + { + // The service applies the schema when it starts; a command may run before it ever did. + if (services.GetService<NpgsqlDataSource>() is { } dataSource) + { + await ViGetSchema.ApplyAsync(dataSource, cancellationToken); + } + + switch (args) + { + case ["publish-tazel-plugin", string path]: + { + if (!File.Exists(path)) + { + await errors.WriteLineAsync($"{path} does not exist."); + return 1; + } + + TazelPluginPublishing publishing = services.GetRequiredService<TazelPluginPublishing>(); + PublishResult result = await publishing.PublishAsync( + await File.ReadAllBytesAsync(path, cancellationToken), cancellationToken); + if (!result.Published) + { + await errors.WriteLineAsync(result.Error); + return 1; + } + + TazelPluginDescriptor plugin = result.Plugin!; + await output.WriteLineAsync( + $"Published {plugin.Publisher}.{plugin.Name} {plugin.Version}: " + + $"https://viget.progmasoft.com/dslplugins/tazel/{plugin.Publisher}/{plugin.Name}"); + return 0; + } + case ["yank-tazel-plugin", string publisher, string name, string version, .. var rest] + when rest is [] or ["--undo"]: + { + bool yanked = rest is []; + ITazelPluginCatalog catalog = services.GetRequiredService<ITazelPluginCatalog>(); + if (!await catalog.SetYankedAsync(publisher, name, version, yanked, cancellationToken)) + { + await errors.WriteLineAsync($"{publisher}.{name} has no version {version}."); + return 1; + } + + await output.WriteLineAsync( + $"{publisher}.{name} {version} is {(yanked ? "yanked" : "no longer yanked")}."); + return 0; + } + default: + await errors.WriteLineAsync( + "usage: viget publish-tazel-plugin <jar>\n" + + " viget yank-tazel-plugin <Publisher> <Name> <Version> [--undo]"); + return 2; + } + } +} |