mirror of
https://github.com/yarlson/lnk.git
synced 2025-08-30 17:59:47 +02:00
Add new output formatting system with flags for color and emoji control: - Introduce OutputConfig and Writer structs for flexible output handling - Add --colors and --emoji/--no-emoji global flags - Refactor commands to use new Writer for consistent formatting - Separate error content from presentation for better flexibility
237 lines
5.3 KiB
Go
237 lines
5.3 KiB
Go
package cmd
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"github.com/spf13/cobra"
|
|
|
|
"github.com/yarlson/lnk/internal/core"
|
|
)
|
|
|
|
func newListCmd() *cobra.Command {
|
|
cmd := &cobra.Command{
|
|
Use: "list",
|
|
Short: "📋 List files managed by lnk",
|
|
Long: "Display all files and directories currently managed by lnk.",
|
|
SilenceUsage: true,
|
|
SilenceErrors: true,
|
|
RunE: func(cmd *cobra.Command, args []string) error {
|
|
host, _ := cmd.Flags().GetString("host")
|
|
all, _ := cmd.Flags().GetBool("all")
|
|
|
|
if host != "" {
|
|
// Show specific host configuration
|
|
return listHostConfig(cmd, host)
|
|
}
|
|
|
|
if all {
|
|
// Show all configurations (common + all hosts)
|
|
return listAllConfigs(cmd)
|
|
}
|
|
|
|
// Default: show common configuration
|
|
return listCommonConfig(cmd)
|
|
},
|
|
}
|
|
|
|
cmd.Flags().StringP("host", "H", "", "List files for specific host")
|
|
cmd.Flags().BoolP("all", "a", false, "List files for all hosts and common configuration")
|
|
return cmd
|
|
}
|
|
|
|
func listCommonConfig(cmd *cobra.Command) error {
|
|
lnk := core.NewLnk()
|
|
w := GetWriter(cmd)
|
|
|
|
managedItems, err := lnk.List()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(managedItems) == 0 {
|
|
w.Writeln(Message{Text: "No files currently managed by lnk (common)", Emoji: "📋", Bold: true}).
|
|
WriteString(" ").
|
|
Write(Info("Use ")).
|
|
Write(Bold("lnk add <file>")).
|
|
WritelnString(" to start managing files")
|
|
return w.Err()
|
|
}
|
|
|
|
countText := fmt.Sprintf("Files managed by lnk (common) (%d item", len(managedItems))
|
|
if len(managedItems) > 1 {
|
|
countText += "s"
|
|
}
|
|
countText += "):"
|
|
|
|
w.Writeln(Message{Text: countText, Emoji: "📋", Bold: true}).
|
|
WritelnString("")
|
|
|
|
for _, item := range managedItems {
|
|
w.WriteString(" ").
|
|
Writeln(Link(item))
|
|
}
|
|
|
|
w.WritelnString("").
|
|
Write(Info("Use ")).
|
|
Write(Bold("lnk status")).
|
|
WritelnString(" to check sync status")
|
|
return w.Err()
|
|
}
|
|
|
|
func listHostConfig(cmd *cobra.Command, host string) error {
|
|
lnk := core.NewLnk(core.WithHost(host))
|
|
w := GetWriter(cmd)
|
|
|
|
managedItems, err := lnk.List()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if len(managedItems) == 0 {
|
|
w.Writeln(Message{Text: fmt.Sprintf("No files currently managed by lnk (host: %s)", host), Emoji: "📋", Bold: true}).
|
|
WriteString(" ").
|
|
Write(Info("Use ")).
|
|
Write(Bold(fmt.Sprintf("lnk add --host %s <file>", host))).
|
|
WritelnString(" to start managing files")
|
|
return w.Err()
|
|
}
|
|
|
|
countText := fmt.Sprintf("Files managed by lnk (host: %s) (%d item", host, len(managedItems))
|
|
if len(managedItems) > 1 {
|
|
countText += "s"
|
|
}
|
|
countText += "):"
|
|
|
|
w.Writeln(Message{Text: countText, Emoji: "📋", Bold: true}).
|
|
WritelnString("")
|
|
|
|
for _, item := range managedItems {
|
|
w.WriteString(" ").
|
|
Writeln(Link(item))
|
|
}
|
|
|
|
w.WritelnString("").
|
|
Write(Info("Use ")).
|
|
Write(Bold("lnk status")).
|
|
WritelnString(" to check sync status")
|
|
return w.Err()
|
|
}
|
|
|
|
func listAllConfigs(cmd *cobra.Command) error {
|
|
w := GetWriter(cmd)
|
|
|
|
// List common configuration
|
|
w.Writeln(Message{Text: "All configurations managed by lnk", Emoji: "📋", Bold: true}).
|
|
WritelnString("")
|
|
|
|
lnk := core.NewLnk()
|
|
commonItems, err := lnk.List()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
countText := fmt.Sprintf("Common configuration (%d item", len(commonItems))
|
|
if len(commonItems) > 1 {
|
|
countText += "s"
|
|
}
|
|
countText += "):"
|
|
|
|
w.Writeln(Message{Text: countText, Emoji: "🌐", Bold: true})
|
|
|
|
if len(commonItems) == 0 {
|
|
w.WriteString(" ").
|
|
Writeln(Colored("(no files)", ColorGray))
|
|
} else {
|
|
for _, item := range commonItems {
|
|
w.WriteString(" ").
|
|
Writeln(Link(item))
|
|
}
|
|
}
|
|
|
|
// Find all host-specific configurations
|
|
hosts, err := findHostConfigs()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, host := range hosts {
|
|
w.WritelnString("").
|
|
Write(Message{Text: fmt.Sprintf("Host: %s", host), Emoji: "🖥️", Bold: true})
|
|
|
|
hostLnk := core.NewLnk(core.WithHost(host))
|
|
hostItems, err := hostLnk.List()
|
|
if err != nil {
|
|
w.WriteString(" ").
|
|
Writeln(Colored(fmt.Sprintf("(error: %v)", err), ColorRed))
|
|
continue
|
|
}
|
|
|
|
countText := fmt.Sprintf(" (%d item", len(hostItems))
|
|
if len(hostItems) > 1 {
|
|
countText += "s"
|
|
}
|
|
countText += "):"
|
|
|
|
w.WriteString(countText).
|
|
WritelnString("")
|
|
|
|
if len(hostItems) == 0 {
|
|
w.WriteString(" ").
|
|
Writeln(Colored("(no files)", ColorGray))
|
|
} else {
|
|
for _, item := range hostItems {
|
|
w.WriteString(" ").
|
|
Writeln(Link(item))
|
|
}
|
|
}
|
|
}
|
|
|
|
w.WritelnString("").
|
|
Write(Info("Use ")).
|
|
Write(Bold("lnk list --host <hostname>")).
|
|
WritelnString(" to see specific host configuration")
|
|
return w.Err()
|
|
}
|
|
|
|
func findHostConfigs() ([]string, error) {
|
|
repoPath := getRepoPath()
|
|
|
|
// Check if repo exists
|
|
if _, err := os.Stat(repoPath); os.IsNotExist(err) {
|
|
return []string{}, nil
|
|
}
|
|
|
|
entries, err := os.ReadDir(repoPath)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
var hosts []string
|
|
for _, entry := range entries {
|
|
name := entry.Name()
|
|
// Look for .lnk.<hostname> files
|
|
if strings.HasPrefix(name, ".lnk.") && name != ".lnk" {
|
|
host := strings.TrimPrefix(name, ".lnk.")
|
|
hosts = append(hosts, host)
|
|
}
|
|
}
|
|
|
|
return hosts, nil
|
|
}
|
|
|
|
func getRepoPath() string {
|
|
xdgConfig := os.Getenv("XDG_CONFIG_HOME")
|
|
if xdgConfig == "" {
|
|
homeDir, err := os.UserHomeDir()
|
|
if err != nil {
|
|
xdgConfig = "."
|
|
} else {
|
|
xdgConfig = filepath.Join(homeDir, ".config")
|
|
}
|
|
}
|
|
return filepath.Join(xdgConfig, "lnk")
|
|
}
|