Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

parse_complete_callback() prevents values from a config from being assigned #1089

Open
The0Dev opened this issue Nov 18, 2024 · 2 comments
Open

Comments

@The0Dev
Copy link

The0Dev commented Nov 18, 2024

Hello. I've run into a strange issue. When I use the parse_complete_callback() function, values for options specified in a config file are not assigned to their respective variables. In this case, the flag_sub variable is always set to false, despite the fact that the config_to_str() function shows that --flag-sub=true.

./app sub

config.toml:

[sub]
flag-sub=true
#include <CLI/CLI.hpp>

struct Options
{
    bool flag_sub = false;
};

void SetupSub(CLI::App& app)
{
    auto opt = std::make_shared<Options>();

    auto* sub = app.add_subcommand("sub", "A subcommand");

    sub->add_flag("--flag-sub,!--no-flag-sub", opt->flag_sub, "flag sub")->default_val(false);
    //flag_sub is false
    //comment out this to fix the issue
    sub->parse_complete_callback([opt]()
    {
        std::cout << "Running the parse complete callback for the sub; flag-sub: " << opt->flag_sub << std::endl;
    });
    //flag_sub is still false unless you remove parse_complete_callback
    sub->callback([opt]()
    {
        std::cout << "Running the callback for the sub; flag-sub: " << opt->flag_sub << std::endl;
    });
}


int main(int argc, char** argv)
{
    CLI::App app{"My app"};

    //Specify your path to the config
    app.set_config("--conf", "/home/user/config.toml", "Set a config for the app");

    argv = app.ensure_utf8(argv);

    app.fallthrough();

    app.require_subcommand(0, 1);

    SetupSub(app);

    try
    {
        app.parse(argc, argv);
        std::cout << app.config_to_str() << std::endl;
    }
    catch(const CLI::ParseError &e)
    {
        return app.exit(e);
    }

}

The following is mentioned in README:

If the main app or subcommand has a config file, no data from the config file will be reflected in parse_complete_callback

Is it the case? Is it also expected that in a regular callback() no data from a config is available? The reason for such behavior is not immediately clear.

@phlptp
Copy link
Collaborator

phlptp commented Dec 30, 2024

The difference is that parse complete is run as soon as parsing the command line is completed. For some subcommands this means it can be called multiple times if multiple duplicate subcommands. This occurs prior to any processing of config file.

The regular callback is completed after all processing is completed, in which case all processing of config files will have been completed.

@The0Dev
Copy link
Author

The0Dev commented Jan 11, 2025

Thank you for your response.

The difference is that parse complete is run as soon as parsing the command line is completed. For some subcommands this means it can be called multiple times if multiple duplicate subcommands. This occurs prior to any processing of config file.

This clarifies some things. This detail should probably be mentioned in the code documentation.

The regular callback is completed after all processing is completed, in which case all processing of config files will have been completed.

In the code example I provided, the value of flag_sub does not match the value that is used in the config file when regular callback is evoked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants