Skip to content

Commit

Permalink
feat: adds validators and updates readme
Browse files Browse the repository at this point in the history
  • Loading branch information
1x-eng committed Oct 30, 2024
1 parent ed1adc7 commit b3f9f44
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 25 deletions.
63 changes: 38 additions & 25 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package config

import (
"fmt"
"os"
"strconv"
"time"
)
Expand All @@ -18,33 +17,31 @@ type Config struct {
}

func LoadConfig() (*Config, error) {
pomoDuration, _ := time.ParseDuration("25m")
shortBreak, _ := time.ParseDuration("5m")
longBreak, _ := time.ParseDuration("15m")
cyclesBeforeLongBreak := 4
if err := validateEnvVars(); err != nil {
return nil, err
}

if val, exists := os.LookupEnv("POMODORO_DURATION"); exists {
if d, err := time.ParseDuration(val); err == nil {
pomoDuration = d
}
pomoDuration, err := parseDurationEnv("POMODORO_DURATION", "25m")
if err != nil {
return nil, fmt.Errorf("invalid POMODORO_DURATION: %w", err)
}
if val, exists := os.LookupEnv("SHORT_BREAK_DURATION"); exists {
if d, err := time.ParseDuration(val); err == nil {
shortBreak = d
}

shortBreak, err := parseDurationEnv("SHORT_BREAK_DURATION", "5m")
if err != nil {
return nil, fmt.Errorf("invalid SHORT_BREAK_DURATION: %w", err)
}
if val, exists := os.LookupEnv("LONG_BREAK_DURATION"); exists {
if d, err := time.ParseDuration(val); err == nil {
longBreak = d
}

longBreak, err := parseDurationEnv("LONG_BREAK_DURATION", "15m")
if err != nil {
return nil, fmt.Errorf("invalid LONG_BREAK_DURATION: %w", err)
}
if val, exists := os.LookupEnv("CYCLES_BEFORE_LONGBREAK"); exists {
if n, err := strconv.Atoi(val); err == nil {
cyclesBeforeLongBreak = n
}

cycles, err := parseIntEnv("CYCLES_BEFORE_LONGBREAK", 4)
if err != nil {
return nil, fmt.Errorf("invalid CYCLES_BEFORE_LONGBREAK: %w", err)
}

contextDir := os.Getenv("TOMATICK_CONTEXT_DIR")
contextDir := getEnvVar("TOMATICK_CONTEXT_DIR")
if contextDir == "" {
contextDir = getDefaultContextDir()
}
Expand All @@ -57,9 +54,25 @@ func LoadConfig() (*Config, error) {
TomatickMementoDuration: pomoDuration,
ShortBreakDuration: shortBreak,
LongBreakDuration: longBreak,
CyclesBeforeLongBreak: cyclesBeforeLongBreak,
MEMAIAPIToken: os.Getenv("MEM_AI_API_TOKEN"),
CyclesBeforeLongBreak: cycles,
MEMAIAPIToken: getEnvVar("MEM_AI_API_TOKEN"),
ContextDir: contextDir,
PerplexityAPIToken: os.Getenv("PERPLEXITY_API_TOKEN"),
PerplexityAPIToken: getEnvVar("PERPLEXITY_API_TOKEN"),
}, nil
}

func parseDurationEnv(key, defaultValue string) (time.Duration, error) {
value := getEnvVar(key)
if value == "" {
value = defaultValue
}
return time.ParseDuration(value)
}

func parseIntEnv(key string, defaultValue int) (int, error) {
value := getEnvVar(key)
if value == "" {
return defaultValue, nil
}
return strconv.Atoi(value)
}
71 changes: 71 additions & 0 deletions config/validation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
package config

import (
"fmt"
"os"
"strings"
)

type EnvVar struct {
Name string
Description string
Required bool
}

var requiredEnvVars = []EnvVar{
{
Name: "MEM_AI_API_TOKEN",
Description: "API token for Mem.ai integration",
Required: true,
},
{
Name: "PERPLEXITY_API_TOKEN",
Description: "API token for Perplexity AI integration",
Required: true,
},
{
Name: "TOMATICK_CONTEXT_DIR",
Description: "Directory for storing context files",
Required: false, // We have a default value
},
{
Name: "POMODORO_DURATION",
Description: "Duration of each Pomodoro cycle (e.g., 25m)",
Required: false, // We have a default value
},
{
Name: "SHORT_BREAK_DURATION",
Description: "Duration of short breaks (e.g., 5m)",
Required: false, // We have a default value
},
{
Name: "LONG_BREAK_DURATION",
Description: "Duration of long breaks (e.g., 15m)",
Required: false, // We have a default value
},
{
Name: "CYCLES_BEFORE_LONGBREAK",
Description: "Number of cycles before a long break",
Required: false, // We have a default value
},
}

func validateEnvVars() error {
var missingVars []string

for _, env := range requiredEnvVars {
if env.Required && strings.TrimSpace(getEnvVar(env.Name)) == "" {
missingVars = append(missingVars, fmt.Sprintf("- %s: %s", env.Name, env.Description))
}
}

if len(missingVars) > 0 {
return fmt.Errorf("missing required environment variables:\n%s\n\nPlease set these environment variables and try again", strings.Join(missingVars, "\n"))
}

return nil
}

func getEnvVar(name string) string {
return strings.TrimSpace(os.Getenv(name))
}
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Yet another pomodoro timer (yes, really) – but this one's your accountability buddy with just enough cognitive wizardry to keep perfectionists from disappearing down the rabbit hole of endless optimizations. Because sometimes "good enough" today beats "perfect" never. :brain: :rocket:

(& Tomatick ?? What the heck is that? Well, it's a combination of "tomato" and "tick" (as in a timer) 🤷 Dad joke? Maybe.)
## Core Features

- **Interactive CLI Interface**: A terminal interface that doesn't suck, with colors and all that jazz
Expand Down

0 comments on commit b3f9f44

Please sign in to comment.