Skip to content

default disabled compose stacks#71

Open
theSoberSobber wants to merge 1 commit into
mainfrom
compose-stack-management
Open

default disabled compose stacks#71
theSoberSobber wants to merge 1 commit into
mainfrom
compose-stack-management

Conversation

@theSoberSobber

@theSoberSobber theSoberSobber commented Dec 1, 2025

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • New Features
    • Added Docker Compose stack management with bulk start, stop, and restart actions
    • Added stack status display and quick file access for stack configurations
    • Added settings toggle to show/hide Compose stack summary cards
    • Extended language support for stack management features (English, Spanish, French)

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai

coderabbitai Bot commented Dec 1, 2025

Copy link
Copy Markdown

Walkthrough

This PR adds internationalization strings for Compose stack management (13 new keys across English, Spanish, and French), extends the DockerContainer model with compose working directory and config files fields, updates the Docker repository to fetch additional Compose labels, and implements a comprehensive Compose stack UI feature in the containers screen with stack action handlers, management cards, and file navigation, plus a new settings toggle for controlling stack card visibility.

Changes

Cohort / File(s) Summary
Localization (i18n keys)
assets/i18n/en-US.json, assets/i18n/es.json, assets/i18n/fr-FR.json
Added 13 translation keys across three languages under containers.* and settings.* namespaces for Compose stack actions (start, stop, restart), statuses, file access, success/failure messages, and a new settings toggle (show_stack_cards) for displaying stack summary cards.
Docker Container Model
lib/domain/models/docker_container.dart
Added two optional fields (composeWorkingDir, composeConfigFiles) to track Compose stack metadata. Extended constructor, copyWithStats, and fromDockerPsLine factory method to parse and propagate the new fields. Added composeProjectPath and _firstComposeConfigFile helper getters.
Docker Repository
lib/data/repositories/docker_repository_impl.dart
Updated docker ps command to request two additional Docker Compose labels: com.docker.compose.project.working_dir and com.docker.compose.project.config_files in formatted output.
Containers Screen UI
lib/presentation/screens/containers_screen.dart
Introduced stack management feature with state tracking (_stackActionsInProgress, _showStackCards), stack information grouping (_buildStackInfos), stack-level action handler (_handleStackAction), stack UI components (_buildStackManagementRow, _buildStackCard), file navigation (_openStackFiles), and helper utilities. Integrated user preference loading for stack card visibility and augmented container rendering.
Settings Screen UI
lib/presentation/screens/settings_screen.dart
Added state variable and SharedPreferences binding for showComposeStackCards preference, implemented _saveShowStackCards persistence method, and rendered a new SwitchListTile UI control for toggling stack card display.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45–60 minutes

Areas requiring extra attention:

  • lib/presentation/screens/containers_screen.dart: Review the new _handleStackAction, _buildStackInfos, and _buildStackCard methods for correct Docker/Compose command construction, error handling, and UI state management during async operations.
  • lib/domain/models/docker_container.dart: Verify token parsing indices (tokens 9 and 10) align with the updated docker ps command format in the repository, and check the _firstComposeConfigFile separator handling (; vs ,).
  • Localization completeness: Confirm all 13 i18n keys are consistently added across all three language files and that template placeholders ({}) in messages are correct.

Possibly related PRs

Poem

🐰 Stacks now dance with cards so grand,
Start and stop at my command,
Compose projects, working right,
Files within, just one quick sight!
Settings toggle, neat and clean,
Best stack UI ever seen! 🌱

Pre-merge checks and finishing touches

❌ Failed checks (1 inconclusive)
Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'default disabled compose stacks' is vague and does not clearly convey the main change. The changeset actually adds comprehensive compose stack management features (UI components, actions, preferences) with the feature defaulting to disabled, but the title's phrasing is ambiguous and could be misunderstood. Clarify the title to better reflect the main change, such as 'Add compose stack management UI with default disabled toggle' or 'Introduce stack management controls for compose projects'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch compose-stack-management

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
lib/presentation/screens/containers_screen.dart (1)

67-84: Consider reducing the frequency of preference reloading.

_loadUserPreferences() is called every 1 second via the server change detection loop. While the method has an early exit if the value hasn't changed (line 91-95), it still performs a SharedPreferences.getInstance() call on every tick, which involves async I/O.

Consider either:

  1. Only reloading preferences when the screen gains focus (via didChangeAppLifecycleState or similar)
  2. Increasing the polling interval for preference changes
  3. Moving preference reload to a less frequent cadence (e.g., every 5-10 seconds)
lib/domain/models/docker_container.dart (1)

157-159: Consider including new fields in toString for debugging.

The toString method could optionally include composeWorkingDir and composeConfigFiles for more complete debugging output.

Apply this diff if enhanced debugging output is desired:

 @override
 String toString() {
-  return 'DockerContainer(id: $id, image: $image, names: $names, status: $status, stack: $composeProject)';
+  return 'DockerContainer(id: $id, image: $image, names: $names, status: $status, stack: $composeProject, workingDir: $composeWorkingDir, configFiles: $composeConfigFiles)';
 }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad3de0e and a82d266.

📒 Files selected for processing (7)
  • assets/i18n/en-US.json (2 hunks)
  • assets/i18n/es.json (2 hunks)
  • assets/i18n/fr-FR.json (2 hunks)
  • lib/data/repositories/docker_repository_impl.dart (1 hunks)
  • lib/domain/models/docker_container.dart (6 hunks)
  • lib/presentation/screens/containers_screen.dart (8 hunks)
  • lib/presentation/screens/settings_screen.dart (4 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build
🔇 Additional comments (21)
lib/data/repositories/docker_repository_impl.dart (1)

62-62: LGTM!

The extended docker ps format correctly adds the two new Compose labels (project.working_dir and project.config_files) to enable stack management features. The pipe-delimited format is consistent with existing fields.

assets/i18n/fr-FR.json (1)

152-163: LGTM!

French translations for the new Compose stack management keys are complete and consistent with the English source. Placeholders are correctly preserved.

Also applies to: 302-303

assets/i18n/es.json (1)

152-163: LGTM!

Spanish translations for the new Compose stack management keys are complete and consistent with the English source.

Also applies to: 302-303

assets/i18n/en-US.json (1)

152-163: LGTM!

New i18n keys for Compose stack management are well-structured and follow existing naming conventions. The placeholder patterns ({}) are appropriately used for dynamic values.

Also applies to: 302-303

lib/presentation/screens/settings_screen.dart (3)

24-24: Verify the intended default value for _showStackCards.

The PR title mentions "default disabled compose stacks", but the code defaults _showStackCards to true both at initialization (line 24) and when loading preferences (line 49). If the intent is to have stack cards disabled by default, this should be false.

Also applies to: 49-49


135-141: LGTM!

The save method correctly persists the toggle state to SharedPreferences with the same key used for loading.


413-423: LGTM!

The SwitchListTile is properly wired to the state variable and save method. The UI placement within the Docker Configuration section is appropriate.

lib/presentation/screens/containers_screen.dart (8)

13-13: LGTM!

New import and state variables are properly scoped for stack management functionality.

Also applies to: 31-32


87-96: LGTM!

The preference loading method correctly guards against unnecessary state updates when the value hasn't changed.


293-322: LGTM!

The _buildStackInfos method correctly groups containers by their compose project and aggregates metadata (working directory, config files, fallback path) with appropriate null-safety handling.


428-431: Shell quoting implementation is correct.

The pattern '$escaped' with ' replaced by '"'"' is a well-known shell escaping technique that handles single quotes within single-quoted strings by:

  1. Ending the single quote
  2. Adding a double-quoted single quote
  3. Resuming the single quote

This is safe for shell command construction.


433-444: LGTM!

The helper maps action names to their localized past-tense labels correctly.


987-1014: LGTM!

The stack management UI components are well-structured with proper state handling for in-progress actions and appropriate button disabling when busy. The horizontal scrollable layout is suitable for varying numbers of stacks.

Also applies to: 1016-1115


1361-1423: LGTM!

The _ComposeStackInfo data class is well-designed with:

  • Clear separation of raw data from computed properties
  • Robust null-safety in getters
  • Logical fallback chain in filesPath and projectDirectory
  • Reasonable canUseComposeCli heuristic (requires project directory or config files with absolute paths)

324-407: Shell quoting implementation is correct and handles edge cases properly.

The _shellQuote function correctly implements POSIX shell single-quote escaping by replacing ' with '"'"' (close quote, escaped quote, open quote) and wrapping the result in single quotes. This approach safely handles all edge cases including empty strings, paths with special characters, and strings with multiple quotes. Container IDs in the fallback branch are safe since they are hex strings. The exception for empty container lists provides appropriate error handling.

lib/domain/models/docker_container.dart (6)

11-12: LGTM: Clean field additions.

The new compose metadata fields follow the existing pattern and are appropriately nullable.


32-33: LGTM: Constructor properly extended.

The new parameters are correctly positioned and follow the established pattern for optional compose metadata.


67-68: LGTM: Fields correctly propagated in copyWithStats.

The new fields are properly carried forward when copying with stats, maintaining consistency with other non-stats fields.


80-80: LGTM: Parsing logic is sound.

The extraction of compose metadata from tokens 9 and 10 follows the existing pattern with appropriate boundary and emptiness checks.

Also applies to: 97-98


140-154: LGTM: Robust config file extraction.

The parsing handles multiple separators, trims whitespace, and filters empty entries appropriately.


123-138: Clarify intent of lastSlash > 0 check for root-level config files.

The condition lastSlash > 0 excludes root-level compose config files (e.g., /docker-compose.yml), returning null instead of /. This appears intentional to avoid returning root as a project path, but it's undocumented and untested. Either add a comment explaining why root paths are excluded, or verify if this should use >= 0 to support root-level files.

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.

2 participants