Skip to content
Merged
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
48 changes: 48 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Configuration

`gcalcli` supports configuration via a `config.toml` file, typically located at `~/.config/gcalcli/config.toml` (or `$XDG_CONFIG_HOME/gcalcli/config.toml`).

## Structure

The configuration is divided into sections:

### `[auth]`

Settings for authentication (Client ID).

### `[calendars]`

Settings for default and ignored calendars.

### `[output]`

Settings for output formatting (week start).

### `[default]` (New)

Set default values for global command-line flags.

```toml
[default]
interactive = false # Disable interactive prompts (simulates --yes)
color = true # Enable/Disable color
conky = false # Conky compatible output
Comment on lines +26 to +29
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section documents interactive = false as “simulates --yes”, but there is no --yes flag in the current CLI (only delete --iamaexpert exists) and the newly-added interactive config key is not used by the application. Update the documentation to describe the actual supported flags/behavior, or implement the promised --yes/non-interactive behavior.

Copilot uses AI. Check for mistakes.
```

## Example `config.toml`

```toml
[auth]
client-id = "your-client-id.apps.googleusercontent.com"

[calendars]
default-calendars = ["Work", "Personal"]
ignore-calendars = ["Holidays"]

[output]
week-start = "monday"

[default]
interactive = true
color = true
```
2 changes: 1 addition & 1 deletion gcalcli/argparsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ def get_argument_parser():
'interactively.',
)
delete.add_argument(
'--iamaexpert', action='store_true', help='Probably not'
'--iamaexpert', action='store_true', help='Legacy alias for --yes'
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The help text says this is a legacy alias for --yes, but --yes is not defined anywhere in the argument parser. Either add a real --yes option (and make --iamaexpert an alias), or adjust the help text to describe the actual behavior (skips the delete confirmation prompt).

Suggested change
'--iamaexpert', action='store_true', help='Legacy alias for --yes'
'--iamaexpert',
action='store_true',
help='Skip delete confirmation prompt (legacy expert flag)',

Copilot uses AI. Check for mistakes.
)

sub.add_parser(
Expand Down
17 changes: 8 additions & 9 deletions gcalcli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,17 +193,16 @@ def main():
opts_from_config = config.Config()

namespace_from_config = opts_from_config.to_argparse_namespace()
# Pull week_start aside and set it manually after parse_known_args.
# TODO: Figure out why week_start from opts_from_config getting through.
week_start = namespace_from_config.week_start
namespace_from_config.week_start = None

# Apply config values as defaults for the parser.
# This allows config to override program defaults, while still letting
# explicit CLI arguments override config.
parser.set_defaults(**vars(namespace_from_config))

if parsed_args.includeRc:
argv = fromfile_args + argv
(parsed_args, unparsed) = parser.parse_known_args(
argv, namespace=namespace_from_config
)
if parsed_args.week_start is None:
parsed_args.week_start = week_start
(parsed_args, unparsed) = parser.parse_known_args(argv)

Comment on lines +197 to +205
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This changes how config values are applied to argparse (switching to set_defaults). There are existing parser unit tests in tests/test_argparsers.py, but no tests asserting that values from config.toml become parser defaults and that explicit CLI args still win (e.g., week_start and boolean flags like --nocolor). Adding a targeted test would help prevent regressions in this precedence logic.

Copilot uses AI. Check for mistakes.
if parsed_args.config_folder:
parsed_args.config_folder = parsed_args.config_folder.expanduser()

Expand Down
27 changes: 27 additions & 0 deletions gcalcli/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,30 @@ class OutputSection(BaseModel):
)


class DefaultSection(BaseModel):
model_config = ConfigDict(
title='Default Global Options'
)

interactive: bool = Field(
alias='interactive',
title='Enable interactive mode (default: true)',
default=True
)
Comment on lines +77 to +82
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interactive is introduced as a configurable value, but it doesn't correspond to any argparse option (parsed_args.interactive is never referenced) and therefore has no effect. Either wire it to an existing flag (e.g. delete --iamaexpert / add a real --yes flag, or map it to a prompt/noprompt behavior), or remove/rename this field to match an actually-consumed option name.

Suggested change
interactive: bool = Field(
alias='interactive',
title='Enable interactive mode (default: true)',
default=True
)

Copilot uses AI. Check for mistakes.

color: bool = Field(
alias='color',
title='Enable color output (default: true)',
default=True
)

conky: bool = Field(
alias='conky',
title='Enable conky color codes',
default=False
)


class Config(BaseModel):
"""User configuration for gcalcli command-line tool.

Expand All @@ -84,6 +108,7 @@ class Config(BaseModel):
auth: AuthSection = Field(default_factory=AuthSection)
calendars: CalendarsSection = Field(default_factory=CalendarsSection)
output: OutputSection = Field(default_factory=OutputSection)
default: DefaultSection = Field(default_factory=DefaultSection)

@classmethod
def from_toml(cls, config_file):
Expand All @@ -98,6 +123,8 @@ def to_argparse_namespace(self) -> argparse.Namespace:
kwargs.update(vars(self.calendars))
if self.output:
kwargs.update(vars(self.output))
if self.default:
kwargs.update(vars(self.default))
return argparse.Namespace(**kwargs)
Comment on lines 108 to 128
Copy link

Copilot AI Feb 17, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Config now supports a [default] section and merges it into the argparse namespace. There are currently no unit tests covering TOML parsing for this new section (or verifying that its values appear in to_argparse_namespace()), despite the repository having a tests/ suite. Please add a test that loads a minimal TOML with [default] and asserts the resulting namespace contains the expected values.

Copilot uses AI. Check for mistakes.

@classmethod
Expand Down