Lee-W commented on code in PR #48403:
URL: https://github.com/apache/airflow/pull/48403#discussion_r2017997811


##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,144 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --dry-run: flag (optional)
+            Dry-run mode (print the changes without modifying airflow.cfg)
+            Example: --dry-run
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Dry-run mode (print the changes without modifying airflow.cfg):
+            airflow config update --dry-run
+
+    :param args: The CLI arguments for updating configuration.
+    """
+    console = AirflowConsole()
+    changes_applied = []

Review Comment:
   ```suggestion
       changes_applied: list[str] = []
   ```



##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,144 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --dry-run: flag (optional)
+            Dry-run mode (print the changes without modifying airflow.cfg)
+            Example: --dry-run
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Dry-run mode (print the changes without modifying airflow.cfg):
+            airflow config update --dry-run

Review Comment:
   ```suggestion
           2. Dry-run mode (print the changes without modifying airflow.cfg):
               airflow config update --dry-run
   
           3. Update only the 'core' and 'database' sections:
               airflow config update --section core,database
   
           4. Update only specific options:
               airflow config update --option sql_alchemy_conn,dag_concurrency
   
           5. Ignore updates for a specific section:
               airflow config update --ignore-section webserver
   ```
   
   I probably would move dry-run to the front



##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,144 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --dry-run: flag (optional)
+            Dry-run mode (print the changes without modifying airflow.cfg)
+            Example: --dry-run
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Dry-run mode (print the changes without modifying airflow.cfg):
+            airflow config update --dry-run
+
+    :param args: The CLI arguments for updating configuration.
+    """
+    console = AirflowConsole()
+    changes_applied = []
+    modifications = ConfigModifications()
+
+    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=True,
+        include_cmds=True,
+        include_secret=True,
+    )
+    for change in CONFIGS_CHANGES:
+        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]
+
+        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"Updated default value of '{conf_section}/{conf_option}' 
from '{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"Renamed '{conf_section}/{conf_option}' to 
'{change.renamed_to.section.lower()}/{change.renamed_to.option.lower()}'."
+            )
+        elif change.was_removed:
+            modifications.add_remove(conf_section, conf_option)
+            changes_applied.append(f"Removed '{conf_section}/{conf_option}' 
from configuration.")
+
+    backup_path = AIRFLOW_CONFIG + ".bak"

Review Comment:
   ```suggestion
       backup_path = f"{AIRFLOW_CONFIG}.bak"
   ```



##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,122 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --verbose: flag (optional)
+            Enable detailed output, including a summary of changes and any 
ignored items.
+            Example: --verbose
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Enable verbose output for more detailed information:
+            airflow config update --verbose
+
+    :param args: The CLI arguments for updating configuration.
+    """
+    console = AirflowConsole()
+    changes_applied = []
+
+    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 []
+
+    for change in CONFIGS_CHANGES:
+        conf_section = change.config.section
+        conf_option = change.config.option
+
+        if update_sections is not None and conf_section not in update_sections:
+            continue
+        if update_options is not None and conf_option not in update_options:
+            continue
+        if conf_section in ignore_sections or conf_option in ignore_options:
+            continue
+
+        if not conf.has_option(conf_section, conf_option, 
lookup_from_deprecated=False):
+            continue
+
+        current_value = conf.get(conf_section, conf_option)
+
+        if change.default_change and (str(current_value) != 
str(change.new_default)):
+            conf.set(conf_section, conf_option, str(change.new_default))
+            changes_applied.append(
+                f"Updated default value of '{conf_section}/{conf_option}' from 
'{current_value}' to '{change.new_default}'."
+            )

Review Comment:
   let's create an issue for tracking that



##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,144 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --dry-run: flag (optional)
+            Dry-run mode (print the changes without modifying airflow.cfg)
+            Example: --dry-run
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Dry-run mode (print the changes without modifying airflow.cfg):
+            airflow config update --dry-run
+
+    :param args: The CLI arguments for updating configuration.
+    """
+    console = AirflowConsole()
+    changes_applied = []
+    modifications = ConfigModifications()
+
+    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=True,
+        include_cmds=True,
+        include_secret=True,
+    )
+    for change in CONFIGS_CHANGES:
+        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]
+
+        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"Updated default value of '{conf_section}/{conf_option}' 
from '{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"Renamed '{conf_section}/{conf_option}' to 
'{change.renamed_to.section.lower()}/{change.renamed_to.option.lower()}'."
+            )
+        elif change.was_removed:
+            modifications.add_remove(conf_section, conf_option)
+            changes_applied.append(f"Removed '{conf_section}/{conf_option}' 
from configuration.")
+
+    backup_path = 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 getattr(args, "dry_run", False):

Review Comment:
   would like to confirm whether we really need to use `getattr` here?



##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,144 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --dry-run: flag (optional)
+            Dry-run mode (print the changes without modifying airflow.cfg)
+            Example: --dry-run
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Dry-run mode (print the changes without modifying airflow.cfg):
+            airflow config update --dry-run

Review Comment:
   It makes more sense for a user to run dry run first before actually run the 
update



##########
airflow-core/src/airflow/configuration.py:
##########
@@ -549,6 +573,88 @@ def _write_value(
         if needs_separation:
             file.write("\n")
 
+    def write_custom_config(
+        self,
+        file: IO[str],
+        comment_out_defaults: bool = True,
+        include_descriptions: bool = True,
+        extra_spacing: bool = True,
+        modifications: ConfigModifications | None = None,
+    ) -> None:
+        """
+        Write a configuration file using a ConfigModifications object.
+
+        This method includes only options from the current airflow.cfg. For 
each option:
+          - If it's marked for removal, omit it.
+          - If renamed, output it under its new name and add a comment 
indicating its original location.
+          - If a default update is specified, apply the new default and output 
the option as a commented line.
+          - Otherwise, if the current value equals the default and 
comment_out_defaults is True, output it as a comment.
+        Options absent from the current airflow.cfg are omitted.
+
+        :param file: File to write the configuration.
+        :param comment_out_defaults: If True, options whose value equals the 
default are written as comments.
+        :param include_descriptions: Whether to include section descriptions.
+        :param extra_spacing: Whether to insert an extra blank line after each 
option.
+        :param modifications: ConfigModifications instance with rename, 
remove, and default updates.
+        """
+        modifications = modifications or ConfigModifications()
+        output: dict[str, list[tuple[str, str, bool, str]]] = {}
+
+        for section in self._sections:  # type: ignore[attr-defined]  # 
accessing _sections from ConfigParser
+            for option, orig_value in self._sections[section].items():  # 
type: ignore[attr-defined]
+                key = (section.lower(), option.lower())
+                if key in modifications.remove:
+                    continue
+
+                mod_comment = ""
+                if key in modifications.rename:
+                    new_sec, new_opt = modifications.rename[key]
+                    effective_section = new_sec
+                    effective_option = new_opt
+                    mod_comment += f"# Renamed from {section}.{option}\n"
+                else:
+                    effective_section = section
+                    effective_option = option
+
+                value = orig_value
+                if key in modifications.default_updates:
+                    mod_comment += (
+                        f"# Default updated from {orig_value} to 
{modifications.default_updates[key]}\n"
+                    )
+                    value = modifications.default_updates[key]
+
+                default_value = self.get_default_value(effective_section, 
effective_option, fallback="")
+                is_default = str(value) == str(default_value)
+                output.setdefault(effective_section.lower(), []).append(
+                    (effective_option, str(value), is_default, mod_comment)
+                )
+
+        for section, options in output.items():
+            section_buffer = StringIO()
+            section_buffer.write(f"[{section}]\n")
+            if include_descriptions:
+                description = self.configuration_description.get(section, 
{}).get("description", "")
+                if description:
+                    for line in description.splitlines():
+                        section_buffer.write(f"# {line}\n")
+                    section_buffer.write("\n")
+            for option, value_str, is_default, mod_comment in options:
+                key = (section.lower(), option.lower())
+                if key in modifications.default_updates and 
comment_out_defaults:
+                    section_buffer.write(f"# {option} = {value_str}\n")
+                else:
+                    if mod_comment:
+                        section_buffer.write(mod_comment)
+                    if is_default and comment_out_defaults:
+                        section_buffer.write(f"# {option} = {value_str}\n")
+                    else:
+                        section_buffer.write(f"{option} = {value_str}\n")
+                if extra_spacing:
+                    section_buffer.write("\n")
+            content = section_buffer.getvalue().strip()
+            if content:
+                file.write(content + "\n\n")

Review Comment:
   ```suggestion
                   file.write(f"{content}\n\n")
   ```



##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,144 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --dry-run: flag (optional)
+            Dry-run mode (print the changes without modifying airflow.cfg)
+            Example: --dry-run
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Dry-run mode (print the changes without modifying airflow.cfg):
+            airflow config update --dry-run
+
+    :param args: The CLI arguments for updating configuration.
+    """
+    console = AirflowConsole()
+    changes_applied = []
+    modifications = ConfigModifications()
+
+    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=True,
+        include_cmds=True,
+        include_secret=True,
+    )
+    for change in CONFIGS_CHANGES:
+        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]
+
+        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"Updated default value of '{conf_section}/{conf_option}' 
from '{current_value}' to '{change.new_default}'."
+                )

Review Comment:
   ```suggestion
           if change.default_change and str(current_value) != 
str(change.new_default):
               modifications.add_default_update(conf_section, conf_option, 
str(change.new_default))
               changes_applied.append(
                   f"Updated default value of '{conf_section}/{conf_option}' 
from '{current_value}' to '{change.new_default}'."
               )
   ```
   
   we might not need this nested if ?



##########
airflow-core/src/airflow/cli/commands/config_command.py:
##########
@@ -704,3 +705,144 @@ def lint_config(args) -> None:
         console.print("\n[red]Please update your configuration file 
accordingly.[/red]")
     else:
         console.print("[green]No issues found in your airflow.cfg. It is ready 
for Airflow 3![/green]")
+
+
+@providers_configuration_loaded
+def update_config(args) -> None:
+    """
+    Update the airflow.cfg file to migrate configuration changes from Airflow 
2.x to Airflow 3.
+
+    This command scans the current configuration file for parameters that have 
been renamed,
+    removed, or had their default values changed in Airflow 3.0, and 
automatically updates
+    the configuration file.
+
+    CLI Arguments:
+        --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
+
+        --dry-run: flag (optional)
+            Dry-run mode (print the changes without modifying airflow.cfg)
+            Example: --dry-run
+
+    Examples:
+        1. Update the entire configuration file:
+            airflow config update
+
+        2. Update only the 'core' and 'database' sections:
+            airflow config update --section core,database
+
+        3. Update only specific options:
+            airflow config update --option sql_alchemy_conn,dag_concurrency
+
+        4. Ignore updates for a specific section:
+            airflow config update --ignore-section webserver
+
+        5. Dry-run mode (print the changes without modifying airflow.cfg):
+            airflow config update --dry-run
+
+    :param args: The CLI arguments for updating configuration.
+    """
+    console = AirflowConsole()
+    changes_applied = []
+    modifications = ConfigModifications()
+
+    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=True,
+        include_cmds=True,
+        include_secret=True,
+    )
+    for change in CONFIGS_CHANGES:
+        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]
+
+        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"Updated default value of '{conf_section}/{conf_option}' 
from '{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"Renamed '{conf_section}/{conf_option}' to 
'{change.renamed_to.section.lower()}/{change.renamed_to.option.lower()}'."

Review Comment:
   ```suggestion
                   (
                       f"Renamed '{conf_section}/{conf_option}' to "
                       
f"'{change.renamed_to.section.lower()}/{change.renamed_to.option.lower()}'."
                   )
   ```
   
   let's break this line to 2



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to