-
Notifications
You must be signed in to change notification settings - Fork 7
feat: add --tags flag to start and stop commands #104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add the ability to start and stop multiple templates by tag filter. Changes: - Add GetByTags() function to retrieve templates matching given tags - Add --tags/-t flag to start command for starting multiple templates - Add --tags/-t flag to stop command for stopping multiple templates - Tags support case-insensitive and substring matching - --id and --tags are mutually exclusive - Continue on failure and report failed templates at end Usage: vt start --tags sqli,xss # Start all templates with sqli OR xss tags vt stop --tags web # Stop all templates with web tag Closes #101
WalkthroughThis PR adds tag-based template selection to the start and stop commands, complementing the existing ID-based approach. It introduces a new Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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 (4)
pkg/template/template.go (1)
223-238: Minor: Redundant exact-match check.The
strings.EqualFoldcheck on line 231 is redundant because the subsequentstrings.Contains(strings.ToLower(...), strings.ToLower(...))on line 232 already covers exact matches. However, the explicit check may improve readability by showing intent, so this is purely optional.🔎 Optional simplification
func templateMatchesTags(tmpl *Template, filterTags []string) bool { for _, filterTag := range filterTags { filterTag = strings.TrimSpace(filterTag) if filterTag == "" { continue } for _, templateTag := range tmpl.Info.Tags { - if strings.EqualFold(templateTag, filterTag) || - strings.Contains(strings.ToLower(templateTag), strings.ToLower(filterTag)) { + if strings.Contains(strings.ToLower(templateTag), strings.ToLower(filterTag)) { return true } } } return false }internal/cli/stop.go (1)
66-83: Consider exiting with non-zero status on partial failures.When some templates fail to stop, the command logs a warning but exits successfully. For CI/scripting scenarios, a non-zero exit code when
len(failed) > 0would better signal partial failure.🔎 Proposed change
if len(failed) > 0 { log.Warn().Msgf("failed to stop %d templates: %s", len(failed), strings.Join(failed, ", ")) + log.Fatal().Msgf("completed with %d failures", len(failed)) } if stopped > 0 { log.Info().Msgf("successfully stopped %d templates", stopped) }Alternatively, use
os.Exit(1)after logging to allow the success message to print first.internal/cli/start.go (2)
79-81: Consider exiting with non-zero status on partial failures.Same concern as in
stop.go: when some templates fail to start, the command logs a warning but exits with status 0. This may cause issues in CI/automation scenarios.
99-114: Inconsistent post-install log message format.In
startTemplate(line 107), the log says"Post-installation instructions:"without the template ID, while in the tags-based loop (line 70), it includes the template ID:"Post-installation instructions for %s:". Consider aligning these for consistency.🔎 Proposed fix
func (c *CLI) startTemplate(provider interface{ Start(*tmpl.Template) error }, template *tmpl.Template, providerName string) { err := provider.Start(template) if err != nil { log.Fatal().Msgf("%v", err) } if len(template.PostInstall) > 0 { - log.Info().Msg("Post-installation instructions:") + log.Info().Msgf("Post-installation instructions for %s:", template.ID) for _, instruction := range template.PostInstall { fmt.Printf(" %s\n", instruction) } } log.Info().Msgf("%s template is running on %s", template.ID, providerName) }
📜 Review details
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
internal/cli/start.gointernal/cli/stop.gopkg/template/template.gopkg/template/template_test.go
🧰 Additional context used
🧬 Code graph analysis (2)
internal/cli/start.go (3)
pkg/provider/registry/registry.go (1)
GetProvider(19-22)pkg/template/template.go (4)
GetByID(192-198)GetByTags(203-221)Info(27-39)Template(17-24)internal/cli/cli.go (1)
CLI(29-32)
internal/cli/stop.go (2)
pkg/provider/registry/registry.go (1)
GetProvider(19-22)pkg/template/template.go (3)
GetByID(192-198)Info(27-39)GetByTags(203-221)
⏰ 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: Analyze (go)
🔇 Additional comments (7)
pkg/template/template.go (1)
199-221: LGTM! Well-structured tag-based retrieval.The implementation correctly:
- Validates for empty tags input
- Creates copies to avoid pointer aliasing issues when iterating over map values
- Returns a clear error when no templates match
pkg/template/template_test.go (2)
34-101: Comprehensive test coverage forGetByTags.The test cases cover all documented behaviors:
- Single and multiple tag matching (OR logic)
- Case-insensitive matching
- Substring matching
- Error cases (no matches, empty tags)
- Whitespace handling
103-128: Good unit tests fortemplateMatchesTags.The helper function is well tested with edge cases including empty and whitespace-only filter tags.
internal/cli/stop.go (2)
28-38: LGTM! Clear mutual exclusivity validation.The validation correctly enforces that exactly one of
--idor--tagsmust be provided.
95-96: LGTM! Flag definition is consistent with start command.internal/cli/start.go (2)
28-38: LGTM! Consistent with stop command validation.
100-100: The current inline interface is the better approach. The function only uses theStartmethod, and the existingProviderinterface inpkg/provider/provider.goincludes four methods (Name(),Start(),Stop(),Status()). Using the fullProviderinterface would violate the Interface Segregation Principle by coupling the function to methods it doesn't use. The inline interface is cleaner and makes testing/mocking easier.
Summary
--tags/-tflag tostartcommand for starting multiple templates by tag--tags/-tflag tostopcommand for stopping multiple templates by tagGetByTags()helper function for retrieving templates matching given tagsUsage
Features
--tags SQLImatches templates with "sqli" tag--tags owamatches templates with "owasp" tag--idand--tagscannot be used togetherTest plan
GetByTags()functiontemplateMatchesTags()helperCloses #101
Summary by CodeRabbit
--idto target a specific template or--tagsto batch-operate on multiple templates matching the provided tags. These options are mutually exclusive, and at least one is required.✏️ Tip: You can customize this high-level summary in your review settings.