Read-only mirrors. Development, issues and pull requests are on GitHub.

summaryrefslogtreecommitdiffhomepage
path: root/apps/api/ViGet/ViGetCommand.cs
blob: ad99aeecc6d91cca8780d5601af9c9d7d8dfc1d2 (plain)
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
// 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 &lt;jar&gt;</c> and <c>viget yank-tazel-plugin &lt;Publisher&gt; &lt;Name&gt;
/// &lt;Version&gt; [--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;
        }
    }
}