aboutsummaryrefslogtreecommitdiff
path: root/src/nix/main.cc
blob: ec9b58b20fe8da8bfa14cc622ef0df9ec427e747 (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
#include <algorithm>

#include "command.hh"
#include "common-args.hh"
#include "eval.hh"
#include "globals.hh"
#include "legacy.hh"
#include "shared.hh"
#include "store-api.hh"
#include "progress-bar.hh"
#include "finally.hh"

extern std::string chrootHelperName;

void chrootHelper(int argc, char * * argv);

namespace nix {

struct NixArgs : virtual MultiCommand, virtual MixCommonArgs
{
    NixArgs() : MultiCommand(*RegisterCommand::commands), MixCommonArgs("nix")
    {
        mkFlag('h', "help", "show usage information", [&]() { showHelpAndExit(); });

        mkFlag(0, "help-config", "show configuration options", [=]() {
            std::cout << "The following configuration options are available:\n\n";
            Table2 tbl;
            for (const auto & s : settings._getSettings())
                if (!s.second.isAlias)
                    tbl.emplace_back(s.first, s.second.setting->description);
            printTable(std::cout, tbl);
            throw Exit();
        });

        mkFlag(0, "version", "show version information", std::bind(printVersion, programName));

        std::string cat = "config";
        settings.convertToArgs(*this, cat);
        hiddenCategories.insert(cat);
    }

    void printFlags(std::ostream & out) override
    {
        Args::printFlags(out);
        std::cout <<
            "\n"
            "In addition, most configuration settings can be overriden using '--<name> <value>'.\n"
            "Boolean settings can be overriden using '--<name>' or '--no-<name>'. See 'nix\n"
            "--help-config' for a list of configuration settings.\n";
    }

    void showHelpAndExit()
    {
        printHelp(programName, std::cout);
        std::cout << "\nNote: this program is EXPERIMENTAL and subject to change.\n";
        throw Exit();
    }
};

void mainWrapped(int argc, char * * argv)
{
    verbosity = lvlError;
    settings.verboseBuild = false;

    /* The chroot helper needs to be run before any threads have been
       started. */
    if (argc > 0 && argv[0] == chrootHelperName) {
        chrootHelper(argc, argv);
        return;
    }

    initNix();
    initGC();

    string programName = baseNameOf(argv[0]);

    {
        auto legacy = (*RegisterLegacyCommand::commands)[programName];
        if (legacy) return legacy(argc, argv);
    }

    NixArgs args;

    args.parseCmdline(argvToStrings(argc, argv));

    if (!args.command) args.showHelpAndExit();

    Finally f([]() { stopProgressBar(); });

    if (isatty(STDERR_FILENO))
        startProgressBar();

    args.command->prepare();
    args.command->run();
}

}

int main(int argc, char * * argv)
{
    return nix::handleExceptions(argv[0], [&]() {
        nix::mainWrapped(argc, argv);
    });
}