Skip to content

feat(profile): add --profile flag and port/settings isolation - #167

Open
TimeToBuildBob wants to merge 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:feat/profile
Open

feat(profile): add --profile flag and port/settings isolation#167
TimeToBuildBob wants to merge 2 commits into
ActivityWatch:masterfrom
TimeToBuildBob:feat/profile

Conversation

@TimeToBuildBob

Copy link
Copy Markdown
Contributor

Part of ActivityWatch/activitywatch#1399 (isolated profiles per edition/mode).

Python aw-server half of the profile work. --profile NAME picks the instance; --testing is an alias for --profile testing. Existing behaviour is unchanged for no-flag and --testing (port 5600 / 5666, settings.json / settings-testing.json, [server] / [server-testing]).

  • Resolve + validate the profile (aw_server/profile.py) — same rule as aw-qt and aw-server-rust: lowercase alphanumeric plus -/_, max 32 chars.
  • Export AW_PROFILE before loading config so aw-core#149 isolates data/config/cache/log under activitywatch-<profile>.
  • Default profile unsets AW_PROFILE instead of setting it to "default". aw-core suffixes any non-empty value, so AW_PROFILE=default would resolve to activitywatch-default and orphan an existing install.
  • Settings filename keeps the existing -testing suffix; named profiles get settings-<profile>.json (redundant under dir isolation, same shape as today).
  • Config section [server-<profile>], falling back to [server] with a warning that the port may collide with 5600. No hash-to-port table — the research build bakes port = 5667 into its own config (phase 5).
  • /api/0/info reports profile so the webui can badge the instance.

Testing-root note

Python aw-core#149 maps AW_PROFILE=testing to activitywatch-testing. The rust isolation branch keeps testing on the bare activitywatch root so existing sqlite-testing.db files are not orphaned. This PR follows the already-merged python dirs contract; unifying the rust testing root is a follow-up on that isolation PR, not a special case here.

Not in this PR

  • aw-client (profile= / --profile) — sibling PR
  • aw-server-rust#652 / aw-qt#128 / aw-tauri#241 — already open
  • Research-build baked port (phase 5)

Verification

  • pytest tests/test_server.py tests/test_profile.py tests/test_profile_config.py --benchmark-disable — 46 passed, 1 skipped (dir-isolation skipif on aw-core < 0.5.17; lock still pins 0.5.16)
  • mypy aw_server tests --ignore-missing-imports — clean

--testing stays as an alias for --profile testing. The profile is
exported as AW_PROFILE before config load so aw-core dirs isolate
data/config; settings keep the existing -testing filename suffix
and named profiles get the same shape. /api/0/info reports profile.

The default profile unsets AW_PROFILE rather than setting it to
"default", because aw-core suffixes any non-empty value (so
AW_PROFILE=default would become activitywatch-default).

Part of ActivityWatch/activitywatch#1399.
@greptile-apps

greptile-apps Bot commented Aug 25, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds named server profiles while preserving the existing default and testing behavior.

  • Resolves and validates --profile, with --testing retained as an alias for the testing profile.
  • Exports the selected profile before configuration loading and selects profile-specific configuration sections, settings filenames, and API metadata.
  • Updates the aw-core lock entry and adds profile-resolution, configuration, settings, and API tests.

Confidence Score: 5/5

The PR appears safe to merge because no unacknowledged blocking failure remains.

No blocking failure remains.

Important Files Changed

Filename Overview
aw_server/profile.py Adds profile validation, CLI-resolution helpers, environment export, and filename suffix behavior.
aw_server/main.py Integrates profile selection into startup before configuration loading and preserves testing-mode semantics.
aw_server/config.py Defers configuration loading and adds profile-section and default-port helpers.
aw_server/settings.py Selects persistent settings filenames from the effective profile.
aw_server/api.py Adds the effective profile to server metadata returned by the information endpoint.
tests/test_profile_config.py Covers profile-specific CLI, configuration, port, environment, settings filename, and dependency-gated directory behavior.
poetry.lock Updates the locked aw-core package from 0.5.16 to 0.5.17.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    CLI[CLI flags] --> Resolve[Resolve and validate profile]
    Resolve --> Export[Export or unset AW_PROFILE]
    Export --> Config[Load profile configuration]
    Config --> Section[Select server profile section]
    Section --> Runtime[Create runtime settings]
    Runtime --> Server[Start server and datastore]
    Server --> API[Expose profile through info API]
Loading

Reviews (2): Last reviewed commit: "chore: lock aw-core 0.5.17 (latest PyPI)" | Re-trigger Greptile

Comment thread aw_server/main.py
Profile-aware dirs from ActivityWatch/aw-core#149 are on git master but
not on PyPI — 0.5.17 was cut in 2024. AW_PROFILE export is a no-op until
the next aw-core release; this lock bump is just current PyPI.
@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

@greptileai review

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

CI-green and mergeable (Greptile 5/5) — waiting only on a maintainer click.

This PR is ready to merge, but the bot has pull-only access to this repo and can't self-merge — surfacing it here so it isn't lost. The monitoring loop will stop re-flagging it now that this note is posted.

@TimeToBuildBob

Copy link
Copy Markdown
Contributor Author

Automated merge handoff for b9f6a30200b9:

  • CI gate: satisfied
  • Review threads: clear
  • Self-merge: blocked — pull-only access on this repo, and these paths are outside the allowlist:
  • aw_server/api.py
  • aw_server/config.py
  • aw_server/main.py
  • aw_server/profile.py
  • aw_server/rest.py
  • aw_server/settings.py
  • Makefile
  • poetry.lock

This head is ready for maintainer review and manual merge. Project monitoring
marked it human_merge_required and will not spend retry sessions attempting an
automated merge. A new head will be evaluated independently.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant