66 "fmt"
77 "os"
88 "os/exec"
9+ "os/user"
910 "path/filepath"
1011 "text/template"
1112
@@ -31,7 +32,7 @@ func NewMacDaemonInstaller(baseFolder, user string) *MacDaemonInstaller {
3132}
3233
3334func (m * MacDaemonInstaller ) Check () error {
34- cmd := exec .Command ("launchctl" , "print" , "system /" + m .serviceName )
35+ cmd := exec .Command ("launchctl" , "print" , "user/" + fmt . Sprintf ( "%d" , os . Getuid ()) + " /"+ m .serviceName )
3536 if err := cmd .Run (); err == nil {
3637 return nil
3738 }
@@ -41,13 +42,16 @@ func (m *MacDaemonInstaller) Check() error {
4142func (m * MacDaemonInstaller ) CheckAndStopExistingService () error {
4243 color .Yellow .Println ("🔍 Checking if service is running..." )
4344
44- if err := m .Check (); err != nil {
45- return err
46- }
47-
48- color .Yellow .Println ("🛑 Stopping existing service..." )
49- if err := exec .Command ("launchctl" , "unload" , fmt .Sprintf ("/Library/LaunchDaemons/%s.plist" , m .serviceName )).Run (); err != nil {
50- return fmt .Errorf ("failed to stop existing service: %w" , err )
45+ if err := m .Check (); err == nil {
46+ color .Yellow .Println ("🛑 Stopping existing service..." )
47+ currentUser , err := user .Current ()
48+ if err != nil {
49+ return fmt .Errorf ("failed to get current user: %w" , err )
50+ }
51+ agentPath := filepath .Join (currentUser .HomeDir , "Library/LaunchAgents" , fmt .Sprintf ("%s.plist" , m .serviceName ))
52+ if err := exec .Command ("launchctl" , "unload" , agentPath ).Run (); err != nil {
53+ return fmt .Errorf ("failed to stop existing service: %w" , err )
54+ }
5155 }
5256 return nil
5357}
@@ -62,6 +66,12 @@ func (m *MacDaemonInstaller) InstallService(username string) error {
6266 return fmt .Errorf ("failed to create daemon directory: %w" , err )
6367 }
6468
69+ // Create logs directory if not exists
70+ logsPath := filepath .Join (m .baseFolder , "logs" )
71+ if err := os .MkdirAll (logsPath , 0755 ); err != nil {
72+ return fmt .Errorf ("failed to create logs directory: %w" , err )
73+ }
74+
6575 plistPath := filepath .Join (daemonPath , fmt .Sprintf ("%s.plist" , m .serviceName ))
6676 if _ , err := os .Stat (plistPath ); err == nil {
6777 if err := os .Remove (plistPath ); err != nil {
@@ -84,7 +94,19 @@ func (m *MacDaemonInstaller) RegisterService() error {
8494 if m .baseFolder == "" {
8595 return fmt .Errorf ("base folder is not set" )
8696 }
87- plistPath := fmt .Sprintf ("/Library/LaunchDaemons/%s.plist" , m .serviceName )
97+
98+ currentUser , err := user .Current ()
99+ if err != nil {
100+ return fmt .Errorf ("failed to get current user: %w" , err )
101+ }
102+
103+ // Create LaunchAgents directory if it doesn't exist
104+ launchAgentsDir := filepath .Join (currentUser .HomeDir , "Library/LaunchAgents" )
105+ if err := os .MkdirAll (launchAgentsDir , 0755 ); err != nil {
106+ return fmt .Errorf ("failed to create LaunchAgents directory: %w" , err )
107+ }
108+
109+ plistPath := filepath .Join (launchAgentsDir , fmt .Sprintf ("%s.plist" , m .serviceName ))
88110 if _ , err := os .Stat (plistPath ); err != nil {
89111 sourceFile := filepath .Join (m .baseFolder , fmt .Sprintf ("daemon/%s.plist" , m .serviceName ))
90112 if err := os .Symlink (sourceFile , plistPath ); err != nil {
@@ -96,7 +118,14 @@ func (m *MacDaemonInstaller) RegisterService() error {
96118
97119func (m * MacDaemonInstaller ) StartService () error {
98120 color .Yellow .Println ("🚀 Starting service..." )
99- if err := exec .Command ("launchctl" , "load" , fmt .Sprintf ("/Library/LaunchDaemons/%s.plist" , m .serviceName )).Run (); err != nil {
121+
122+ currentUser , err := user .Current ()
123+ if err != nil {
124+ return fmt .Errorf ("failed to get current user: %w" , err )
125+ }
126+
127+ agentPath := filepath .Join (currentUser .HomeDir , "Library/LaunchAgents" , fmt .Sprintf ("%s.plist" , m .serviceName ))
128+ if err := exec .Command ("launchctl" , "load" , agentPath ).Run (); err != nil {
100129 return fmt .Errorf ("failed to start service: %w" , err )
101130 }
102131 return nil
@@ -106,14 +135,22 @@ func (m *MacDaemonInstaller) UnregisterService() error {
106135 if m .baseFolder == "" {
107136 return fmt .Errorf ("base folder is not set" )
108137 }
138+
139+ currentUser , err := user .Current ()
140+ if err != nil {
141+ return fmt .Errorf ("failed to get current user: %w" , err )
142+ }
143+
144+ agentPath := filepath .Join (currentUser .HomeDir , "Library/LaunchAgents" , fmt .Sprintf ("%s.plist" , m .serviceName ))
145+
109146 color .Yellow .Println ("🛑 Stopping service if running..." )
110147 // Try to stop the service first
111- _ = exec .Command ("launchctl" , "unload" , fmt . Sprintf ( "/Library/LaunchDaemons/%s.plist" , m . serviceName ) ).Run ()
148+ _ = exec .Command ("launchctl" , "unload" , agentPath ).Run ()
112149
113- color .Yellow .Println ("🗑 Removing service files..." )
114- // Remove symlink from LaunchDaemons
115- if err := os .Remove (fmt . Sprintf ( "/Library/LaunchDaemons/%s.plist" , m . serviceName ) ); err != nil && ! os .IsNotExist (err ) {
116- return fmt .Errorf ("failed to remove launch daemon plist: %w" , err )
150+ color .Yellow .Println ("🗑 Removing service files..." )
151+ // Remove symlink from LaunchAgents
152+ if err := os .Remove (agentPath ); err != nil && ! os .IsNotExist (err ) {
153+ return fmt .Errorf ("failed to remove launch agent plist: %w" , err )
117154 }
118155
119156 color .Green .Println ("✅ Service unregistered successfully" )
@@ -126,7 +163,8 @@ func (m *MacDaemonInstaller) GetDaemonServiceFile(username string) (buf bytes.Bu
126163 return
127164 }
128165 err = tmpl .Execute (& buf , map [string ]string {
129- "UserName" : username ,
166+ "UserName" : username ,
167+ "BaseFolder" : m .baseFolder ,
130168 })
131169 return
132170}
0 commit comments