scalascopt

Scala scopt: argument required() based on one or more other arguments


I am used to use Scala scopt for command line option parsing. You can choose whether an argument is .required() by calling the just shown function.

How can I define an argument that is required only if another argument has been defined? For instance, I have a flag --writeToSnowflake defined via scopt like this:

opt[Unit]("writeToSnowflake")
    .action((_, config) => config.copy(writeToSnowflake = true))

If I choose that a job writes to snowflake, a set of other arguments become mandatory. For instance, --snowflake_table, --snowflake_database, etc.

How can I achieve it?


Solution

  • I discovered that .children() can be used outside of .cmd()s to achieve what I asked. This is an example:

    If the parent is specified, in this case if --snowflake is "passed" hence evaluates to True, then the children that are .required() will throw an error if they are null (but only when the parent is specified, like in my case).

    opt[Unit]("snowflake")
            .action((_, config) => config.copy(writeToSnowflake = true))
            .text("optional flag for writing to Snowflake")
            .children(
              opt[Unit]("snowflake_incremental_writing")
                .action((_, config) => config.copy(snowflakeIncrementalWriting = true))
                .text("optional flag for enabling incremental writing"),
              opt[Map[String, String]]("snowflake_options")
                .required()
                .action((snowflakeOptions, config) => config.copy(snowflakeOptions = snowflakeOptions))
                .text("options for writing to snowflake: user, privateKey, warehouse, database, schema, and table")
            )