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
4 changes: 3 additions & 1 deletion internal/checks/circular.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"fmt"
"sort"
"strings"

"rev-dep-go/internal/emoji"
)

// findCircularDependencies detects circular dependencies in the dependency tree
Expand Down Expand Up @@ -234,7 +236,7 @@ func findDeterministicCycle(start string, adj map[string][]string, inSCC map[str
func formatCircularDependencies(cycles [][]string, pathPrefix string, deps MinimalDependencyTree, includeHeader bool, baseIndentation int) string {
if len(cycles) == 0 {
if includeHeader {
return fmt.Sprintln("✅ No circular dependencies found! ")
return fmt.Sprintln(emoji.Success + " No circular dependencies found! ")
}
return ""
}
Expand Down
23 changes: 12 additions & 11 deletions internal/cli/config_init.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/spf13/cobra"

"rev-dep-go/internal/config"
"rev-dep-go/internal/emoji"
globutil "rev-dep-go/internal/glob"
"rev-dep-go/internal/monorepo"
"rev-dep-go/internal/pathutil"
Expand Down Expand Up @@ -774,41 +775,41 @@ func packageDirsToSortedRelPaths(cwd string, packageDirs []string) []string {

// printInitConfigResults prints the results of config initialization
func printInitConfigResults(result *initConfigResult) {
fmt.Printf(" Created .rev-dep.config.jsonc at %s\n", result.configPath)
fmt.Printf("%s Created .rev-dep.config.jsonc at %s\n", emoji.Success, result.configPath)

fmt.Println()
switch {
case result.createdForMonorepoSubPackage:
fmt.Printf("⚠️ Created config for monorepo sub-package. This file targets the current package only.\n")
fmt.Printf("%s Created config for monorepo sub-package. This file targets the current package only.\n", emoji.Warning)
case result.isMonorepo:
if len(result.workspacePackagePaths) > 0 {
fmt.Printf("📦 Monorepo detected: discovered %d workspace %s and created a rule for each:\n", len(result.workspacePackagePaths), packagesWord(len(result.workspacePackagePaths)))
fmt.Printf("%s Monorepo detected: discovered %d workspace %s and created a rule for each:\n", emoji.Package, len(result.workspacePackagePaths), packagesWord(len(result.workspacePackagePaths)))
for _, relPath := range result.workspacePackagePaths {
fmt.Printf(" - %s\n", relPath)
}
} else {
fmt.Printf("📦 Monorepo detected: no workspace packages found.\n")
fmt.Printf("%s Monorepo detected: no workspace packages found.\n", emoji.Package)
}
case result.rootHasPackageJson:
fmt.Printf("📁 Created a rule for the root package.\n")
fmt.Printf("%s Created a rule for the root package.\n", emoji.Rule)
case len(result.standalonePackagePaths) == 0:
fmt.Printf("📁 No package.json found; created a single rule for the root directory.\n")
fmt.Printf("%s No package.json found; created a single rule for the root directory.\n", emoji.Rule)
default:
fmt.Printf("📁 No root package.json found; created rules for standalone packages only.\n")
fmt.Printf("%s No root package.json found; created rules for standalone packages only.\n", emoji.Rule)
}

// Separate section for standalone packages discovered in subdirectories.
if len(result.standalonePackagePaths) > 0 {
fmt.Println()
fmt.Printf("🧩 Discovered %d standalone %s in subdirectories (not part of a monorepo) and created a rule for each:\n", len(result.standalonePackagePaths), packagesWord(len(result.standalonePackagePaths)))
fmt.Printf("%s Discovered %d standalone %s in subdirectories (not part of a monorepo) and created a rule for each:\n", emoji.Standalone, len(result.standalonePackagePaths), packagesWord(len(result.standalonePackagePaths)))
for _, relPath := range result.standalonePackagePaths {
fmt.Printf(" - %s\n", relPath)
}
}

if result.entryPointsDetected {
fmt.Println()
fmt.Printf("🔎 Auto-detected entry points for %d %s (production/development classified by path).\n", result.entryPointPackageCount, packagesWord(result.entryPointPackageCount))
fmt.Printf("%s Auto-detected entry points for %d %s (production/development classified by path).\n", emoji.Search, result.entryPointPackageCount, packagesWord(result.entryPointPackageCount))
}

fmt.Println()
Expand All @@ -820,6 +821,6 @@ func printInitConfigResults(result *initConfigResult) {
}

fmt.Println()
fmt.Printf("📖 Integration guide: %s\n", integrationGuide)
fmt.Printf("🛟 Troubleshooting: https://rev-dep.com/troubleshooting\n\n")
fmt.Printf("%s Integration guide: %s\n", emoji.Guide, integrationGuide)
fmt.Printf("%s Troubleshooting: https://rev-dep.com/troubleshooting\n\n", emoji.Troubleshooting)
}
42 changes: 18 additions & 24 deletions internal/cli/config_lint.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/spf13/cobra"

"rev-dep-go/internal/config"
"rev-dep-go/internal/emoji"
"rev-dep-go/internal/pathutil"
)

Expand All @@ -21,13 +22,6 @@ var (
lintConfigRules []string
)

// errorMark / warnMark are the finding bullets: colorful emoji (red ❌, yellow ⚠️)
// consistent with the ✅/✍️ markers used elsewhere in the output.
const (
errorMark = "❌"
warnMark = "⚠️"
)

var configLintCmd = &cobra.Command{
Use: "lint",
Short: "Report (and optionally remove) config glob/path patterns that match nothing",
Expand Down Expand Up @@ -75,7 +69,7 @@ them by hand.`,
errorsRemaining, warnings := countLintFindings(result, lintConfigFix)

printConfigLintStatus(errorsRemaining, warnings, lintConfigFix)
fmt.Printf(" Done in %dms.\n", time.Since(startTime).Milliseconds())
fmt.Printf("%s Done in %dms.\n", emoji.Done, time.Since(startTime).Milliseconds())

if errorsRemaining > 0 {
os.Exit(1)
Expand Down Expand Up @@ -114,13 +108,13 @@ func printConfigLintStatus(errors, warnings int, fixed bool) {
case errors == 0 && warnings == 0:
// "all clean" already printed by the results section
case errors == 0:
fmt.Printf("\n⚠️ %d warning(s), no errors — exit 0.\n", warnings)
fmt.Printf("\n%s %d warning(s), no errors — exit 0.\n", emoji.Warning, warnings)
default:
verb := "found"
if fixed {
verb = "remaining after --fix"
}
fmt.Printf("\n %d error(s) %s, %d warning(s).\n", errors, verb, warnings)
fmt.Printf("\n%s %d error(s) %s, %d warning(s).\n", emoji.Error, errors, verb, warnings)
}
}

Expand All @@ -144,7 +138,7 @@ func printConfigLintResults(result *config.LintResult, cwd string) {
for i, r := range result.RulesRun {
ruleNames[i] = string(r)
}
fmt.Printf("🔍 Config lint: %s [rules: %s]\n", configRel, strings.Join(ruleNames, ", "))
fmt.Printf("%s Config lint: %s [rules: %s]\n", emoji.Search, configRel, strings.Join(ruleNames, ", "))

var errorDeads, warningDeads []config.DeadPattern
for _, dp := range result.DeadPatterns {
Expand All @@ -156,7 +150,7 @@ func printConfigLintResults(result *config.LintResult, cwd string) {
}

if len(errorDeads) == 0 && len(warningDeads) == 0 && len(result.Overlaps) == 0 && result.TrailingCommaCount == 0 && result.CompactableCount == 0 {
fmt.Printf("\n No issues found — every glob matches something, no patterns overlap, config is compact.\n")
fmt.Printf("\n%s No issues found — every glob matches something, no patterns overlap, config is compact.\n", emoji.Success)
return
}

Expand Down Expand Up @@ -184,9 +178,9 @@ func (p *ruleHeaderPrinter) print(ruleIndex int, rulePath string) bool {
return false
}
if ruleIndex < 0 {
fmt.Printf("\n📄 Top-level\n")
fmt.Printf("\n%s Top-level\n", emoji.File)
} else {
fmt.Printf("\n📁 Rule: %s\n", rulePath)
fmt.Printf("\n%s Rule: %s\n", emoji.Rule, rulePath)
}
p.ruleIndex, p.rulePath, p.first = ruleIndex, rulePath, false
return true
Expand All @@ -210,7 +204,7 @@ func printErrorSection(deads []config.DeadPattern) {
if !dp.Removable {
suffix += " [not auto-removed]"
}
fmt.Printf(" %s %q%s\n", errorMark, dp.Value, suffix)
fmt.Printf(" %s %q%s\n", emoji.Error, dp.Value, suffix)
}
}

Expand All @@ -234,12 +228,12 @@ func printWarningSection(warningDeads []config.DeadPattern, overlaps []config.Ov
fmt.Printf("\n── Warnings ──\n")

if trailingCommas > 0 || compactable > 0 {
fmt.Printf("\n📄 File\n")
fmt.Printf("\n%s File\n", emoji.File)
if compactable > 0 {
fmt.Printf(" %s %d detector declaration(s) can be written more compactly — run --fix to simplify\n", warnMark, compactable)
fmt.Printf(" %s %d detector declaration(s) can be written more compactly — run --fix to simplify\n", emoji.Warning, compactable)
}
if trailingCommas > 0 {
fmt.Printf(" %s %d redundant trailing comma(s) — run --fix to remove\n", warnMark, trailingCommas)
fmt.Printf(" %s %d redundant trailing comma(s) — run --fix to remove\n", emoji.Warning, trailingCommas)
}
}

Expand Down Expand Up @@ -306,7 +300,7 @@ func printWarningSection(warningDeads []config.DeadPattern, overlaps []config.Ov
fmt.Printf(" %s\n", label)
lastLabel = label
}
fmt.Printf(" %s %s\n", warnMark, l.text)
fmt.Printf(" %s %s\n", emoji.Warning, l.text)
}
}

Expand All @@ -325,19 +319,19 @@ func kindSuffix(kind config.PatternKind) string {

func printConfigLintFixSummary(fix *config.FixResult) {
if fix.RemovedCount > 0 {
fmt.Printf("\n✍️ Removed %d dead pattern(s).\n", fix.RemovedCount)
fmt.Printf("\n%s Removed %d dead pattern(s).\n", emoji.Fix, fix.RemovedCount)
}
if fix.CompactedCount > 0 {
fmt.Printf("✍️ Simplified %d detector declaration(s) to compact form.\n", fix.CompactedCount)
fmt.Printf("%s Simplified %d detector declaration(s) to compact form.\n", emoji.Fix, fix.CompactedCount)
}
if fix.TrailingCommasRemoved > 0 {
fmt.Printf("✍️ Removed %d redundant trailing comma(s).\n", fix.TrailingCommasRemoved)
fmt.Printf("%s Removed %d redundant trailing comma(s).\n", emoji.Fix, fix.TrailingCommasRemoved)
}
if fix.ReportOnlyKept > 0 {
fmt.Printf("⚠️ %d dead pattern(s) not auto-removed (removing them could change a check's behavior or make the config invalid) — review and remove manually.\n", fix.ReportOnlyKept)
fmt.Printf("%s %d dead pattern(s) not auto-removed (removing them could change a check's behavior or make the config invalid) — review and remove manually.\n", emoji.Warning, fix.ReportOnlyKept)
}
if fix.RemovedCount == 0 && fix.ReportOnlyKept == 0 && fix.TrailingCommasRemoved == 0 && fix.CompactedCount == 0 {
fmt.Printf("\n Nothing to remove.\n")
fmt.Printf("\n%s Nothing to remove.\n", emoji.Success)
}
}

Expand Down
Loading
Loading