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

Add --config-json-path to accept flags specified in a JSON file. #265

Merged
merged 9 commits into from
Aug 21, 2023

Conversation

angela28chen
Copy link
Collaborator

@angela28chen angela28chen commented Aug 10, 2023

Add flag --config-json-path to accept commandline flags that are specified in a JSON file. This flag can be used multiple times. The priority of any conflicting flags is as follows:

later flag on commandline > earlier flag on commandline > flag in later JSON file > flag in earlier JSON file

For flags that accept multiple values, the same priority is used and only flags specified in the same JSON file or flags all on the commandline will be combined.

Detailed changes:

  • Changed map mAllOptions to hold strings instead of string_views since there are now temporary strings originating from the JSON structure, changed some input parameters for CliOptions member functions to match.
  • Created some CommandLineParser methods to aid in parsing options (these are public for unit testing purposes)
    • ParseJson
    • ParseOption
  • Created more methods for CliOptions
    • AddOption overload that accepts one key and a vector of values to reduce the time needed to insert arrays. This function is only used by the JSON parsing flow. On the command line the flag must still be specified multiple times (--flag-name 1,2,3 is still invalid)
    • OverwriteOptions
  • Updated CommandLineParser::Parse
    • Added a second initial pass of argv during commandline parsing to identify any provided JSON config files
    • Implemented overwriting
  • Added mJsonConfigFlagName to CommandLineParser so that the string config-json-path isn't specified in multiple places

@angela28chen angela28chen force-pushed the json-config branch 3 times, most recently from 12d0a8e to 7fe93d3 Compare August 10, 2023 23:13
@angela28chen
Copy link
Collaborator Author

Note: I tried to keep the input parameters for CliOptions as std::string_view in some cases, but I was running into issues with heterogeneous lookup for unordered containers (could get it to work on Windows but not on the current versions of the Android and Linux CI builds)

@angela28chen angela28chen requested a review from Keenuts August 11, 2023 06:03
@Keenuts
Copy link
Member

Keenuts commented Aug 11, 2023

Note: I tried to keep the input parameters for CliOptions as std::string_view in some cases, but I was running into issues with heterogeneous lookup for unordered containers (could get it to work on Windows but not on the current versions of the Android and Linux CI builds)

Arf, that's sad...
Seeing this https://groups.google.com/a/isocpp.org/g/std-proposals/c/oXBQ6WVXLCU
meaning map does supports it since 14(https://en.cppreference.com/w/cpp/container/map/find)

What's sadder is it wasn't done to the unordered_map until c++20 😥
(https://en.cppreference.com/w/cpp/container/unordered_map/find)

So this explains the lack of support, at least from the Android NDK.
Surprising to see clang also refuses it...
Thanks for looking into that!

Copy link
Member

@Keenuts Keenuts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this!
A few things to fix, but overall OK.

The the JSON overriding flags, even when specified after, this is fine IMO. Complexity to manage the ordering is not yet justified. But it should be documented.

std::string value = ss.str();
ss.str("");

if (value.length() > 0 && value.substr(0, 1) == "[") {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you probably shouldn't parse the data again. What about using functions like it->is_array().

@angela28chen
Copy link
Collaborator Author

Thank you for the feedback, I've tried to address it and made two major changes:

  • Better error-reporting for finding/opening/parsing JSON files, and better validation for JSON structure (explicitly checking for when it's expected to be an object/array)
  • Implementing JSON values as lower priority than commandline flags, which involves identifying JSON file paths and adding those options first (since the later ones have higher priority). I combined this with the existing initial pass that splits arguments specified with '='.

Copy link
Collaborator

@apazylbe apazylbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some optional suggestions, otherwise lgtm

@angela28chen angela28chen requested a review from apazylbe August 16, 2023 18:32
Copy link
Member

@Keenuts Keenuts left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot to send the review, sorry!

@angela28chen
Copy link
Collaborator Author

Note: This PR is not ready for submitting.

To summarize the result of the discussion Nathan and I had about the ordering for list arrays, we decided that combining the contents of the JSON file and the commandline flags is confusing, so any time that a list flag is used on the command-line it will completely overwrite the value for that flag specified inside the JSON file.

Detailed example:

file.json: [A, B]
file2.json: [C, D]

./benchmark --config-json-path=file.json 
Final CliOptions: A, B
asset dir search order: A, B, default

./benchmark --config-json-path=file.json --assets-path=E --assets-path=F
Final CliOptions: E, F
asset dir search order: E, F, default

./benchmark --config-json-path=file.json --config-json-path=file2.json
Final CliOptions: C, D
asset dir search order: C, D, default

./benchmark --config-json-path=file.json --config-json-path=file2.json --assets-path=E --assets-path=F 
Final CliOptions: E, F
//asset dir search order: E, F, default

android/linux builds

* Make mAllOptions strings and not string_views
* Make the functions that need to search mAllOptions take input
  parameters of const std::string& instead
* JSON file flags are lower priority than flags specified on the command
  line
* Using JSON is_array and is_object functions
* Using round bracket syntax for initalization
* Fix Parse() function
* Better error reporting for parsing the JSON file
* Fixed flag description typo
* Rename pConfigJsonPath to pConfigJsonPaths
* Change commandline parsing to 2 initial passes for better readability
and command line flags to overwrite json files after that.
@angela28chen
Copy link
Collaborator Author

This is ready for review/merging. I don't have unit tests for commandline VS JSON file priority but I did check it manually and it should behave as described in the previous comment.

@angela28chen angela28chen requested a review from apazylbe August 19, 2023 01:38
@apazylbe apazylbe merged commit 4bdd70e into google:main Aug 21, 2023
@angela28chen angela28chen deleted the json-config branch August 21, 2023 14:44
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

Successfully merging this pull request may close these issues.

3 participants