-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactoring, improved code structure, improved layout and style, flags
- Loading branch information
Showing
14 changed files
with
466 additions
and
155 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package config | ||
|
||
import ( | ||
"flag" | ||
"fmt" | ||
"os" | ||
"keepalive/internal/ui" | ||
"keepalive/internal/util" | ||
) | ||
|
||
type Config struct { | ||
Duration int | ||
ShowVersion bool | ||
} | ||
|
||
func ParseFlags(version string) (*Config, error) { | ||
flags := flag.NewFlagSet("keepalive", flag.ExitOnError) | ||
flags.Usage = func() { | ||
model := ui.InitialModel() | ||
model.ShowHelp = true | ||
fmt.Print(model.View()) | ||
} | ||
|
||
duration := flags.String("duration", "", "Duration to keep system alive (e.g., \"2h30m\")") | ||
flags.StringVar(duration, "d", "", "Duration to keep system alive (e.g., \"2h30m\")") | ||
showVersion := flags.Bool("version", false, "Show version information") | ||
flags.BoolVar(showVersion, "v", false, "Show version information") | ||
|
||
if err := flags.Parse(os.Args[1:]); err != nil { | ||
if err == flag.ErrHelp { | ||
os.Exit(0) | ||
} | ||
return nil, err | ||
} | ||
|
||
if *showVersion { | ||
fmt.Printf("Keep-Alive Version: %s\n", version) | ||
os.Exit(0) | ||
} | ||
|
||
var minutes int | ||
if *duration != "" { | ||
d, err := util.ParseDuration(*duration) | ||
if err != nil { | ||
return nil, fmt.Errorf("error parsing duration: %v", err) | ||
} | ||
minutes = int(d.Minutes()) | ||
} | ||
|
||
return &Config{ | ||
Duration: minutes, | ||
ShowVersion: *showVersion, | ||
}, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,111 +1,81 @@ | ||
package keepalive | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"os/exec" | ||
"runtime" | ||
"sync" | ||
"time" | ||
) | ||
|
||
// Keeper manages the keep-alive state across platforms. | ||
// Keeper manages the system's keep-alive state | ||
type Keeper struct { | ||
mu sync.Mutex | ||
cancel context.CancelFunc | ||
platformStop func() error | ||
running bool | ||
running bool | ||
mu sync.Mutex | ||
timer *time.Timer | ||
} | ||
|
||
// StartIndefinite keeps the system awake indefinitely using platform-specific methods. | ||
// IsRunning returns whether the keep-alive is currently active | ||
func (k *Keeper) IsRunning() bool { | ||
k.mu.Lock() | ||
defer k.mu.Unlock() | ||
return k.running | ||
} | ||
|
||
// StartIndefinite starts keeping the system alive indefinitely | ||
func (k *Keeper) StartIndefinite() error { | ||
k.mu.Lock() | ||
defer k.mu.Unlock() | ||
|
||
if k.running { | ||
return nil | ||
return errors.New("keep-alive already running") | ||
} | ||
|
||
switch runtime.GOOS { | ||
case "windows": | ||
// Windows-specific logic in keepalive_windows.go | ||
if err := setWindowsKeepAlive(); err != nil { | ||
return err | ||
} | ||
k.platformStop = stopWindowsKeepAlive | ||
|
||
case "darwin": | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
cmd := exec.CommandContext(ctx, "caffeinate", "-dims") | ||
if err := cmd.Start(); err != nil { | ||
cancel() | ||
return err | ||
} | ||
k.cancel = func() { | ||
cancel() | ||
_ = cmd.Wait() | ||
} | ||
k.platformStop = func() error { return nil } | ||
|
||
case "linux": | ||
ctx, cancel := context.WithCancel(context.Background()) | ||
// systemd-inhibit prevents the system from going idle/sleep. | ||
cmd := exec.CommandContext(ctx, "systemd-inhibit", "--what=idle", "--mode=block", "bash", "-c", "while true; do sleep 3600; done") | ||
if err := cmd.Start(); err != nil { | ||
cancel() | ||
return err | ||
} | ||
k.cancel = func() { | ||
cancel() | ||
_ = cmd.Wait() | ||
} | ||
k.platformStop = func() error { return nil } | ||
|
||
default: | ||
return errors.New("unsupported platform") | ||
if err := setWindowsKeepAlive(); err != nil { | ||
return err | ||
} | ||
|
||
k.running = true | ||
return nil | ||
} | ||
|
||
// StartTimed keeps the system awake for the specified number of minutes, then stops. | ||
func (k *Keeper) StartTimed(minutes int) error { | ||
if minutes <= 0 { | ||
return errors.New("minutes must be > 0") | ||
// StartTimed starts keeping the system alive for the specified duration | ||
func (k *Keeper) StartTimed(d time.Duration) error { | ||
k.mu.Lock() | ||
defer k.mu.Unlock() | ||
|
||
if k.running { | ||
return errors.New("keep-alive already running") | ||
} | ||
if err := k.StartIndefinite(); err != nil { | ||
|
||
if err := setWindowsKeepAlive(); err != nil { | ||
return err | ||
} | ||
|
||
go func() { | ||
time.Sleep(time.Duration(minutes) * time.Minute) | ||
_ = k.Stop() | ||
}() | ||
k.running = true | ||
k.timer = time.AfterFunc(d, func() { | ||
k.Stop() | ||
}) | ||
|
||
return nil | ||
} | ||
|
||
// Stop stops keeping the system awake, restoring normal behavior. | ||
// Stop stops keeping the system alive | ||
func (k *Keeper) Stop() error { | ||
k.mu.Lock() | ||
defer k.mu.Unlock() | ||
|
||
if !k.running { | ||
return nil | ||
} | ||
if k.cancel != nil { | ||
k.cancel() | ||
|
||
if k.timer != nil { | ||
k.timer.Stop() | ||
k.timer = nil | ||
} | ||
if k.platformStop != nil { | ||
if err := k.platformStop(); err != nil { | ||
return err | ||
} | ||
|
||
if err := stopWindowsKeepAlive(); err != nil { | ||
return err | ||
} | ||
|
||
k.running = false | ||
return nil | ||
} | ||
|
||
// IsRunning returns whether the system is currently being kept awake. | ||
func (k *Keeper) IsRunning() bool { | ||
k.mu.Lock() | ||
defer k.mu.Unlock() | ||
return k.running | ||
} |
Oops, something went wrong.