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

summaryrefslogtreecommitdiffhomepage
path: root/Sources/Main.cpp
blob: 8ea8b898be24eae482167b65b14c9a66a0f654ad (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
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
// SPDX-FileCopyrightText: 2026 Progmasoft <support@progmasoft.com>
// SPDX-License-Identifier: MPL-2.0 WITH AdditionRef-Progmasoft-Exception-2.0

#include <cstdio>
#include <filesystem>
#include <fmt/format.h>
#include <string_view>
#include <vector>

#include "Progmasoft/Tazelish/CommandLine.hpp"
#include "Progmasoft/Tazelish/Help.hpp"
#include "Progmasoft/Tazelish/VersionFiles.hpp"

namespace
{

    namespace fs = std::filesystem;
    namespace tazelish = Progmasoft::Tazelish;

    constexpr int kSuccess = 0;
    constexpr int kFailure = 1;
    constexpr int kUsage = 2;

    int
    Report(const tazelish::FileError &error)
    {
        fmt::print(stderr,
                   "error: {} {}\n",
                   error.file.string(),
                   error.message);
        return kFailure;
    }

    int
    Write(const fs::path &file, const tazelish::Version &version, bool force)
    {
        if (auto error = tazelish::WriteVersionFile(file, version, force))
        {
            return Report(*error);
        }
        fmt::print("Wrote {} to {}\n",
                   tazelish::FormatVersion(version),
                   file.string());
        return kSuccess;
    }

    int
    RunUse(const tazelish::Use &use)
    {
        return Write(fs::path(".") / fs::path(tazelish::kProjectFileName),
                     use.version,
                     use.force);
    }

    int
    RunDefault(const tazelish::Default &choice)
    {
        const auto home = tazelish::HomeDirectory();
        if (!home)
        {
#ifdef _WIN32
            fmt::print(stderr, "error: USERPROFILE is not set\n");
#else
            fmt::print(stderr, "error: HOME is not set\n");
#endif
            return kFailure;
        }
        return Write(tazelish::ConfigFile(*home), choice.version, choice.force);
    }

    // Installing and updating download from static.tazel.net, which this build
    // of Tazelish does not do.
    int
    RunDownloading(std::string_view command)
    {
        fmt::print(
            stderr,
            "error: tazelish {} downloads from static.tazel.net, and this "
            "build of Tazelish does not download\n",
            command);
        return kFailure;
    }

    std::string_view
    SelfName(tazelish::SelfAction action)
    {
        switch (action)
        {
            case tazelish::SelfAction::kUpdate:
                return "self update";
            case tazelish::SelfAction::kRemove:
                return "self remove";
            case tazelish::SelfAction::kPurge:
                return "self purge";
        }
        return "self";
    }

    int
    Run(const tazelish::Command &command)
    {
        if (const auto *help = std::get_if<tazelish::Help>(&command))
        {
            fmt::print("{}", tazelish::HelpText(help->topic));
            return kSuccess;
        }
        if (const auto *use = std::get_if<tazelish::Use>(&command))
        {
            return RunUse(*use);
        }
        if (const auto *choice = std::get_if<tazelish::Default>(&command))
        {
            return RunDefault(*choice);
        }
        if (std::holds_alternative<tazelish::Install>(command))
        {
            return RunDownloading("install");
        }
        return RunDownloading(
            SelfName(std::get<tazelish::Self>(command).action));
    }

} // namespace

int
main(int argc, char **argv)
{
    std::vector<std::string_view> arguments;
    for (int index = 1; index < argc; ++index)
    {
        arguments.emplace_back(argv[index]);
    }
    const auto parsed = tazelish::ParseCommandLine(arguments);
    if (const auto *rejection = std::get_if<tazelish::Rejection>(&parsed))
    {
        fmt::print(stderr, "error: {}\n", rejection->message);
        return kUsage;
    }
    return Run(std::get<tazelish::Command>(parsed));
}