diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 53314ec11e4f0..54ae2510b38df 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1244,7 +1244,8 @@ repos:
providers/|
scripts|
task-sdk/|
- tests/dags/test_imports\.py
+ tests/dags/test_imports\.py|
+ setup_idea\.py
)
require_serial: true
additional_dependencies: ['rich>=12.4.4']
diff --git a/contributing-docs/quick-start-ide/contributors_quick_start_pycharm.rst b/contributing-docs/quick-start-ide/contributors_quick_start_pycharm.rst
index cd40d8310a5b5..7d13dd1c8cd25 100644
--- a/contributing-docs/quick-start-ide/contributors_quick_start_pycharm.rst
+++ b/contributing-docs/quick-start-ide/contributors_quick_start_pycharm.rst
@@ -75,6 +75,33 @@ Setup your project
alt="Invalidate caches and restart Pycharm">
+5. An alternative way to add source roots is to configure the ``airflow.iml`` file under ``.idea`` directory and update the
+ ``module.xml`` file:
+
+ To setup the source roots for all the modules that exist in the project, you can run the following command:
+ This needs to done on the airflow repository root directory. It overwrites the existing ``.idea/airflow.iml`` and
+ ``.idea/modules.xml`` files.
+
+ .. code-block:: bash
+
+ $ python setup_idea.py
+
+ Then Restart the PyCharm/IntelliJ IDEA.
+
+ .. raw:: html
+
+
+
+
+
+ .. raw:: html
+
+
+
+
+
Setting up debugging
####################
diff --git a/contributing-docs/quick-start-ide/images/pycharm-airflow.iml.png b/contributing-docs/quick-start-ide/images/pycharm-airflow.iml.png
new file mode 100644
index 0000000000000..c8a93009df837
Binary files /dev/null and b/contributing-docs/quick-start-ide/images/pycharm-airflow.iml.png differ
diff --git a/contributing-docs/quick-start-ide/images/pycharm-modules.xml.png b/contributing-docs/quick-start-ide/images/pycharm-modules.xml.png
new file mode 100644
index 0000000000000..d70d648534830
Binary files /dev/null and b/contributing-docs/quick-start-ide/images/pycharm-modules.xml.png differ
diff --git a/setup_idea.py b/setup_idea.py
new file mode 100644
index 0000000000000..2f8e75d2b6b4b
--- /dev/null
+++ b/setup_idea.py
@@ -0,0 +1,99 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+from __future__ import annotations
+
+import os
+
+iml_xml_template = """
+
+
+
+ {SOURCE_ROOT_MODULE_PATH}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"""
+
+module_xml_template = """
+
+
+
+
+
+
+"""
+
+source_root_module_patter: str = ''
+
+source_root_modules: list[str] = ["airflow-core", "airflow-ctl", "dev/breeze", "task-sdk"]
+
+all_module_paths: list[str] = []
+
+ROOT_DIR: str = "./providers"
+
+
+def setup_idea():
+ # Providers discovery
+ for dirpath, _, filenames in os.walk(ROOT_DIR):
+ if "pyproject.toml" in filenames:
+ relative_path = os.path.relpath(dirpath, ROOT_DIR)
+ source_root_modules.append(f"providers/{relative_path}")
+
+ source_root_modules.sort()
+ for module in source_root_modules:
+ all_module_paths.append(source_root_module_patter.format(path=f"{module}/src", status="false"))
+ all_module_paths.append(source_root_module_patter.format(path=f"{module}/test", status="true"))
+
+ source_root_module_path: str = "\n\t\t".join(all_module_paths)
+
+ base_source_root_xml: str = iml_xml_template.format(SOURCE_ROOT_MODULE_PATH=source_root_module_path)
+
+ with open(".idea/airflow.iml", "w") as file:
+ file.write(base_source_root_xml)
+
+ with open(".idea/modules.xml", "w") as file:
+ file.write(module_xml_template)
+
+
+if __name__ == "__main__":
+ user_input = input(
+ "This script will overwrites the .idea/airflow.iml and .idea/modules.xml files. Press Enter Y/N to continue: "
+ )
+ if user_input.lower() == "y":
+ setup_idea()
+ print("Updated airflow.iml and modules.xml files, Now restart the PyCharm/IntelliJ IDEA")
+ else:
+ print("Not updating airflow.iml and modules.xml files")
+ exit(0)