refactor: clean up code from comments

This commit is contained in:
Patryk Hegenberg 2025-04-02 14:21:33 +02:00
parent 4ceed6f301
commit 29bdd3a2a4
8 changed files with 150 additions and 252 deletions

112
cmd.go
View file

@ -12,22 +12,21 @@ import (
func (a *App) setupCommands() *cobra.Command {
rootCmd := &cobra.Command{
Use: "workctl", // Name des CLI-Tools
Use: "workctl",
Short: "Manage work time, connections, and tasks",
Long: `workctl is a command-line interface to streamline common work-related tasks,
including time tracking (using an internal SQLite database), remote connections (SSH, RDP),
and other utilities.`,
Version: "1.0.0-sqlite", // Beispielversion
Version: "1.0.0-sqlite",
}
rootCmd.AddCommand(a.startCommand())
rootCmd.AddCommand(a.stopCommand())
rootCmd.AddCommand(a.showCommand())
rootCmd.AddCommand(a.trackCommand()) // Neuer Befehl für Tracking
rootCmd.AddCommand(a.connectCommands()) // Befehle für Verbindungen gruppieren
rootCmd.AddCommand(a.trackCommand())
rootCmd.AddCommand(a.connectCommands())
rootCmd.AddCommand(a.wakeCommand())
rootCmd.AddCommand(a.importTimewarriorCommand())
// Verberge das Standard 'completion' Kommando, falls nicht gewünscht
rootCmd.CompletionOptions.DisableDefaultCmd = true
return rootCmd
@ -40,7 +39,7 @@ func (a *App) startCommand() *cobra.Command {
Long: "Starts time tracking for 'work', attempts to wake the workstation, and sets up SSH tunnels.",
Run: func(cmd *cobra.Command, args []string) {
fmt.Println("Starting workday procedures...")
a.connect() // Führt Start Tracking, Wake, Tunnel Setup aus
a.connect()
fmt.Println("Workday start initiated. Tunnels are running in the background.")
fmt.Println("Use 'workctl connect rdp' or connect manually.")
},
@ -71,54 +70,6 @@ func (a *App) stopCommand() *cobra.Command {
}
}
// func (a *App) trackCommand() *cobra.Command {
// cmd := &cobra.Command{
// Use: "track [tag]",
// Short: "Start tracking a new tag (stops current)",
// Long: `Starts a new time tracking entry with the specified tag (e.g., 'break', 'meeting', 'projectX').
// This automatically stops any currently running timer.
// If no tag is provided, it stops the current timer and starts 'work'.`,
// Args: cobra.MaximumNArgs(1), // 0 oder 1 Argument
// Run: func(cmd *cobra.Command, args []string) {
// tag := TagWork // Standard-Tag, wenn kein Argument gegeben wird
// if len(args) > 0 {
// tag = args[0]
// }
//
// if tag == "" {
// log.Println("ERROR: Tag cannot be empty.")
// fmt.Println("Usage: workctl track <tag_name>")
// os.Exit(1) // Fehler signalisieren
// }
//
// fmt.Printf("Attempting to start tracking '%s'...\n", tag)
// if err := a.timeStore.StartTracking(tag); err != nil {
// log.Printf("ERROR: Failed to start tracking '%s': %v", tag, err)
// fmt.Printf("Error: Could not start tracking '%s'.\n", tag)
// os.Exit(1)
// } else {
// fmt.Printf("Successfully started tracking '%s'.\n", tag)
// }
// },
// }
// cmd.AddCommand(&cobra.Command{
// Use: "break",
// Short: "Start tracking 'break'",
// Run: func(cmd *cobra.Command, args []string) {
// fmt.Println("Starting break...")
// if err := a.timeStore.StartTracking(TagBreak); err != nil {
// log.Printf("ERROR: Failed to start break tracking: %v", err)
// fmt.Println("Error: Could not start break.")
// os.Exit(1)
// } else {
// fmt.Println("Break started.")
// }
// },
// })
//
// return cmd
// }
func (a *App) trackCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "track [tag]",
@ -130,51 +81,43 @@ If no tag is provided, it stops the current timer and starts 'work'.
If the provided tag is a special full-day tag ('uni', 'urlaub', 'feiertag', 'krank', 'free'),
it will mark the *current day* with that tag instead of starting an interval timer.
This also stops any currently running timer.`,
Args: cobra.MaximumNArgs(1), // 0 oder 1 Argument
RunE: func(cmd *cobra.Command, args []string) error { // RunE für Fehlerbehandlung
tag := TagWork // Standard-Tag, wenn kein Argument gegeben wird
Args: cobra.MaximumNArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
tag := TagWork
if len(args) > 0 {
tag = args[0]
}
if tag == "" {
// Sollte durch Default nicht passieren, aber sicher ist sicher
return fmt.Errorf("tag cannot be empty")
}
tagLower := strings.ToLower(tag)
// Prüfe, ob es ein spezieller Ganztages-Tag ist
switch tagLower {
case "uni", "urlaub", "feiertag", "krank", "free":
today := time.Now()
fmt.Printf("Logging '%s' for today (%s)...\n", tagLower, today.Format("2006-01-02"))
if err := a.timeStore.LogFullDay(tagLower, today); err != nil {
// Loggen passiert in LogFullDay oder bei Fehlern davor
// Gib den Fehler zurück, damit Cobra ihn behandelt
return fmt.Errorf("could not log '%s' for today: %w", tagLower, err)
}
// Erfolgsmeldung kommt aus LogFullDay
return nil // Erfolg
default: // Normale Intervalle wie 'work', 'break', oder unbekannt
default:
fmt.Printf("Attempting to start tracking interval '%s'...\n", tag)
if err := a.timeStore.StartTracking(tag); err != nil {
log.Printf("ERROR: Failed to start tracking '%s': %v", tag, err)
// Gib Fehler zurück
return fmt.Errorf("could not start tracking '%s': %w", tag, err)
}
// Erfolgsmeldung kommt aus StartTracking
return nil // Erfolg
}
},
}
// Alias hinzufügen (bleibt bestehen)
cmd.AddCommand(&cobra.Command{
Use: "break",
Short: "Start tracking 'break'",
RunE: func(cmd *cobra.Command, args []string) error { // RunE verwenden
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println("Starting break...")
if err := a.timeStore.StartTracking(TagBreak); err != nil {
log.Printf("ERROR: Failed to start break tracking: %v", err)
@ -196,16 +139,16 @@ or exports the yearly data to an Excel file.
Periods: today, day, week, month, year (or YYYY-MM-DD)
Export: Use the --export flag or the 'export' subcommand.`,
ValidArgs: []string{"day", "week", "month", "year", "today"}, // Zur Autovervollständigung
ValidArgs: []string{"day", "week", "month", "year", "today"},
Run: func(cmd *cobra.Command, args []string) {
period := "today" // Standard ist heute
period := "today"
if len(args) > 0 {
period = args[0]
}
if a.flags.ShowExport {
filename := a.flags.ExportName
if filename == "" || filename == "Arbeitszeiten.xlsx" { // Standardwert aus Flags anpassen
if filename == "" || filename == "Arbeitszeiten.xlsx" {
filename = "Arbeitszeiten_" + time.Now().Format("2006") + ".xlsx"
log.Printf("INFO: No export name specified, using default: %s", filename)
}
@ -240,7 +183,6 @@ Export: Use the --export flag or the 'export' subcommand.`,
cmd.MarkFlagsMutuallyExclusive("week", "month", "export")
// Füge einen 'export' Unterbefehl hinzu für klarere Nutzung
cmd.AddCommand(&cobra.Command{
Use: "export [filename]",
Short: "Export yearly timetable to Excel",
@ -285,7 +227,7 @@ func (a *App) connectCommands() *cobra.Command {
Short: "Connect to Jump Host (with tunnel to workstation)",
Long: "Establishes an SSH connection to the Jump Host and forwards local port 2048 to the workstation's SSH port (22). This command blocks.",
Run: func(cmd *cobra.Command, args []string) {
a.connectToJump() // Blockiert
a.connectToJump()
},
})
@ -294,7 +236,7 @@ func (a *App) connectCommands() *cobra.Command {
Short: "Connect to Workstation via SSH tunnel",
Long: "Establishes an SSH connection to the Workstation via the local tunnel on port 2048. Also sets up RDP tunnel on local port 6000. Requires the 'jump' tunnel to be active. This command blocks.",
Run: func(cmd *cobra.Command, args []string) {
a.connectToWorkstation() // Blockiert
a.connectToWorkstation()
},
})
@ -303,7 +245,7 @@ func (a *App) connectCommands() *cobra.Command {
Short: "Start RDP session via tunnel",
Long: "Starts an RDP client (xfreerdp) connecting to localhost:6000. Requires an active tunnel forwarding this port to the workstation's RDP port (3389). This command blocks.",
Run: func(cmd *cobra.Command, args []string) {
a.startRDPConnection() // Blockiert
a.startRDPConnection()
},
})
@ -349,7 +291,7 @@ func (a *App) runImport(filepath string) (int, error) {
if err != nil {
return 0, fmt.Errorf("could not begin database transaction: %w", err)
}
defer tx.Rollback() // Rollback wird ausgeführt, wenn Commit nicht erreicht wird
defer tx.Rollback()
stmt, err := tx.Prepare("INSERT INTO time_entries (tag, start_time, end_time) VALUES (?, ?, ?)")
if err != nil {
@ -371,13 +313,8 @@ func (a *App) runImport(filepath string) (int, error) {
var tag, start_str, end_str string
has_date := false
// Versuche, das Format zu erkennen (mit oder ohne Datum am Anfang)
// Format mit Datum: Wk Date Day Tags Start End Time [Total]
// Format ohne Datum: Tags Start End Time [Total]
// Mindestens 4 Felder für Tag, Start, End, Time erwartet
if len(fields) >= 7 && strings.Contains(fields[1], "-") && len(fields[1]) == 10 { // Prüft auf Datum YYYY-MM-DD
current_date_str = fields[1] // Datum merken
if len(fields) >= 7 && strings.Contains(fields[1], "-") && len(fields[1]) == 10 {
current_date_str = fields[1]
tag = fields[3]
start_str = fields[4]
end_str = fields[5]
@ -385,7 +322,7 @@ func (a *App) runImport(filepath string) (int, error) {
} else if len(fields) >= 4 && strings.Contains(fields[1], ":") && strings.Contains(fields[2], ":") {
if current_date_str == "" {
log.Printf("WARN: Skipping line without preceding date: %s", line)
continue // Überspringe Zeile, wenn kein Datum bekannt ist
continue
}
tag = fields[0]
start_str = fields[1]
@ -403,7 +340,7 @@ func (a *App) runImport(filepath string) (int, error) {
log.Printf("WARN: Skipping line with invalid date '%s': %v", current_date_str, err)
continue
}
end_time := start_time.Add(24 * time.Hour) // Ende ist Anfang des nächsten Tages
end_time := start_time.Add(24 * time.Hour)
_, err = stmt.Exec(tag, start_time, end_time)
if err != nil {
@ -411,7 +348,7 @@ func (a *App) runImport(filepath string) (int, error) {
} else {
imported_count++
}
continue // Gehe zur nächsten Zeile nach Behandlung des ganztägigen Eintrags
continue
}
} else {
@ -440,11 +377,6 @@ func (a *App) runImport(filepath string) (int, error) {
log.Printf("WARN: End time is before start time on the same date line, skipping: %s", line)
continue
}
// Wenn kein Datum da war, gehen wir davon aus, dass es sich um Mitternacht handelt.
// Diese Logik ist knifflig und fehleranfällig, da `timew summary` normalerweise aufteilt.
// Einfacher Ansatz: Ignoriere diesen Fall vorerst, da er im Standard-Summary selten auftritt.
// log.Printf("INFO: Detected potential midnight crossing (end %v < start %v) - adjusting end date might be needed if timew split wasn't done.", endTime, startTime)
// endTime = endTime.Add(24 * time.Hour) // Vorsicht mit dieser Annahme!
}
db_tag := strings.ToLower(tag)