def update_config()

in airflow-core/src/airflow/cli/commands/config_command.py [0:0]


def update_config(args) -> None:
    """
    Update the airflow.cfg file to migrate configuration changes from Airflow 2.x to Airflow 3.

    By default, this command will perform a dry-run (showing the changes only) and list only
    the breaking configuration changes by scanning the current configuration file for parameters that have
    been renamed, removed, or had their default values changed in Airflow 3.0. To see or fix all recommended
    changes, use the --all-recommendations argument. To automatically update your airflow.cfg file, use
    the --fix argument. This command cleans up the existing comments in airflow.cfg but creates a backup of
    the old airflow.cfg file.

    CLI Arguments:
        --fix: flag (optional)
            Automatically fix/apply the breaking changes (or all changes if --all-recommendations is also
            specified)
            Example: --fix

        --all-recommendations: flag (optional)
            Include non-breaking (recommended) changes as well as breaking ones.
            Can be used with --fix.
            Example: --all-recommendations

        --section: str (optional)
            Comma-separated list of configuration sections to update.
            Example: --section core,database

        --option: str (optional)
            Comma-separated list of configuration options to update.
            Example: --option sql_alchemy_conn,dag_concurrency

        --ignore-section: str (optional)
            Comma-separated list of configuration sections to ignore during update.
            Example: --ignore-section webserver

        --ignore-option: str (optional)
            Comma-separated list of configuration options to ignore during update.
            Example: --ignore-option check_slas

    Examples:
        1. Dry-run mode (print the changes in modified airflow.cfg) showing only breaking changes:
            airflow config update

        2. Dry-run mode showing all recommendations:
            airflow config update --all-recommendations

        3. Apply (fix) only breaking changes:
            airflow config update --fix

        4. Apply (fix) all recommended changes:
            airflow config update --fix --all-recommendations

        5. Show changes only the specific sections:
            airflow config update --section core,database

        6.Show changes only the specific options:
            airflow config update --option sql_alchemy_conn,dag_concurrency

        7. Ignores the specific section:
            airflow config update --ignore-section webserver

    :param args: The CLI arguments for updating configuration.
    """
    console = AirflowConsole()
    changes_applied: list[str] = []
    modifications = ConfigModifications()

    include_all = args.all_recommendations if args.all_recommendations else False
    apply_fix = args.fix if args.fix else False
    dry_run = not apply_fix
    update_sections = args.section if args.section else None
    update_options = args.option if args.option else None
    ignore_sections = args.ignore_section if args.ignore_section else []
    ignore_options = args.ignore_option if args.ignore_option else []

    config_dict = conf.as_dict(
        display_source=True,
        include_env=False,
        include_cmds=False,
        include_secret=True,
        display_sensitive=True,
    )
    for change in CONFIGS_CHANGES:
        if not include_all and not change.breaking:
            continue
        conf_section = change.config.section.lower()
        conf_option = change.config.option.lower()
        full_key = f"{conf_section}.{conf_option}"

        if update_sections is not None and conf_section not in [s.lower() for s in update_sections]:
            continue
        if update_options is not None and full_key not in [opt.lower() for opt in update_options]:
            continue
        if conf_section in [s.lower() for s in ignore_sections] or full_key in [
            opt.lower() for opt in ignore_options
        ]:
            continue

        if conf_section not in config_dict or conf_option not in config_dict[conf_section]:
            continue
        value_data = config_dict[conf_section][conf_option]
        if not (isinstance(value_data, tuple) and value_data[1] == "airflow.cfg"):
            continue

        current_value = value_data[0]
        prefix = "[[red]BREAKING[/red]]" if change.breaking else "[[yellow]Recommended[/yellow]]"
        if change.default_change:
            if str(current_value) != str(change.new_default):
                modifications.add_default_update(conf_section, conf_option, str(change.new_default))
                changes_applied.append(
                    f"{prefix} Updated default value of '{conf_section}/{conf_option}' from "
                    f"'{current_value}' to '{change.new_default}'."
                )
        if change.renamed_to:
            modifications.add_rename(
                conf_section, conf_option, change.renamed_to.section, change.renamed_to.option
            )
            changes_applied.append(
                f"{prefix} Renamed '{conf_section}/{conf_option}' to "
                f"'{change.renamed_to.section.lower()}/{change.renamed_to.option.lower()}'."
            )
        elif change.was_removed:
            if change.remove_if_equals is not None:
                if str(current_value) == str(change.remove_if_equals):
                    modifications.add_remove(conf_section, conf_option)
                    changes_applied.append(
                        f"{prefix} Removed '{conf_section}/{conf_option}' from configuration."
                    )
            else:
                modifications.add_remove(conf_section, conf_option)
                changes_applied.append(f"{prefix} Removed '{conf_section}/{conf_option}' from configuration.")

    backup_path = f"{AIRFLOW_CONFIG}.bak"
    try:
        shutil.copy2(AIRFLOW_CONFIG, backup_path)
        console.print(f"Backup saved as '{backup_path}'.")
    except Exception as e:
        console.print(f"Failed to create backup: {e}")
        raise AirflowConfigException("Backup creation failed. Aborting update_config operation.")

    if dry_run:
        console.print("[blue]Dry-run mode enabled. No changes will be written to airflow.cfg.[/blue]")
        with StringIO() as config_output:
            conf.write_custom_config(
                file=config_output,
                comment_out_defaults=True,
                include_descriptions=True,
                modifications=modifications,
            )
            new_config = config_output.getvalue()
        console.print(new_config)
    else:
        with open(AIRFLOW_CONFIG, "w") as config_file:
            conf.write_custom_config(
                file=config_file,
                comment_out_defaults=True,
                include_descriptions=True,
                modifications=modifications,
            )

    if changes_applied:
        console.print("[green]The following are the changes in airflow config:[/green]")
        for change_msg in changes_applied:
            console.print(f"  - {change_msg}")
        if dry_run:
            console.print(
                "[blue]Dry-run is mode enabled. To apply above airflow.cfg run the command "
                "with `--fix`.[/blue]"
            )
    else:
        console.print("[green]No updates needed. Your configuration is already up-to-date.[/green]")

    if args.verbose:
        console.print("[blue]Configuration update completed with verbose output enabled.[/blue]")