Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion aider/args.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,19 @@
from .dump import dump # noqa: F401


class YAMLConfigFileParserIgnoreProfiles(configargparse.YAMLConfigFileParser):
"""
A custom YAMLConfigFileParser that removes the top-level 'profiles' key from its result. We use
this to avoid having to set ignore_unknown_config_file_keys=True on our
configargparse.ArgumentParser, which would fail to flag invalid config keys to the user.
"""

def parse(self, stream):
result = super().parse(stream)
result.pop("profiles", None)
return result


def resolve_aiderignore_path(path_str, git_root=None):
path = Path(path_str)
if path.is_absolute():
Expand All @@ -37,7 +50,7 @@ def get_parser(default_config_files, git_root):
description="aider is AI pair programming in your terminal",
add_config_file_help=True,
default_config_files=default_config_files,
config_file_parser_class=configargparse.YAMLConfigFileParser,
config_file_parser_class=YAMLConfigFileParserIgnoreProfiles,
auto_env_var_prefix="AIDER_",
)
# List of valid edit formats for argparse validation & shtab completion.
Expand Down Expand Up @@ -129,6 +142,11 @@ def get_parser(default_config_files, git_root):
default=".aider.model.metadata.json",
help="Specify a file with context window and costs for unknown models",
).complete = shtab.FILE
group.add_argument(
"--profile",
metavar="PROFILE",
help="Include settings from a named profile in the 'profiles' section of the config",
)
group.add_argument(
"--alias",
action="append",
Expand Down
36 changes: 36 additions & 0 deletions aider/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import importlib_resources
import shtab
import yaml
from dotenv import load_dotenv
from prompt_toolkit.enums import EditingMode

Expand Down Expand Up @@ -332,6 +333,16 @@ def generate_search_path_list(default_file, git_root, command_line_file):
return files


def load_profiles_from_config_files(config_files):
profiles = {}
for config_file in config_files:
if Path(config_file).exists():
with open(config_file, "r") as f:
config = yaml.safe_load(f) or {}
profiles.update(config.get("profiles", {}))
return profiles


def register_models(git_root, model_settings_fname, io, verbose=False):
model_settings_files = generate_search_path_list(
".aider.model.settings.yml", git_root, model_settings_fname
Expand Down Expand Up @@ -497,6 +508,31 @@ def main(argv=None, input=None, output=None, force_git_root=None, return_coder=F

args, unknown = parser.parse_known_args(argv)

# Include config from --profile
# - Do this early so profiles can contain settings like --env-file, and cli args override
# profile settings
if args.profile is not None:
profiles = load_profiles_from_config_files(default_config_files)
profile = profiles.get(args.profile)
if not profile:
print(f"Profile not found: {args.profile}", file=sys.stderr)
print(f"Available profiles: {", ".join(profiles.keys())}", file=sys.stderr)
return 1
if args.verbose:
print(f"Using profile: {args.profile}")
profile_argv = []
for k, v in profile.items():
if v is None:
v = ""
if isinstance(v, bool):
profile_argv.append(f"--{k if v else f'no-{k}'}")
else:
profile_argv.append(f"--{k}={v}")
# Inject profile settings into argv (used here and below)
argv = profile_argv + argv
# Parse again with settings from profile
args, unknown = parser.parse_known_args(argv)

# Load the .env file specified in the arguments
loaded_dotenvs = load_dotenv_files(git_root, args.env_file, args.encoding)

Expand Down