15
15
package config
16
16
17
17
import (
18
+ "bytes"
18
19
// we need this for the ArduinoCreateAgent.plist in this package
19
20
_ "embed"
20
21
"os"
@@ -38,33 +39,55 @@ func getLaunchdAgentPath() *paths.Path {
38
39
func InstallPlistFile () {
39
40
launchdAgentPath := getLaunchdAgentPath ()
40
41
if ! launchdAgentPath .Exist () {
41
- err := writePlistFile (launchdAgentPath )
42
- if err != nil {
43
- log .Error (err )
42
+ writeAndLoadPlistFile (launchdAgentPath )
43
+ log .Info ("Quitting, another instance of the agent has been started by launchd" )
44
+ os .Exit (0 )
45
+ } else {
46
+ // we already have an existing launchd plist file, so we check if it's updated
47
+ launchAgentContent , _ := launchdAgentPath .ReadFile ()
48
+ launchAgentContentNew , _ := getLaunchdAgentDefinition ()
49
+ if bytes .Equal (launchAgentContent , launchAgentContentNew ) {
50
+ log .Infof ("the autostart file %s already exists: nothing to do" , launchdAgentPath )
44
51
} else {
45
- err = loadLaunchdAgent () // this will load the agent: basically starting a new instance
46
- if err != nil {
47
- log .Error (err )
48
- } else {
49
- log .Info ("Quitting, another instance of the agent has been started by launchd" )
50
- os .Exit (0 )
51
- }
52
+ log .Infof ("the autostart file %s needs to be updated" , launchdAgentPath )
53
+ removePlistFile ()
54
+ writeAndLoadPlistFile (launchdAgentPath )
52
55
}
53
- } else {
54
- // we already have an existing launchd plist file, so we don't have to do anything
55
- log .Infof ("the autostart file %s already exists: nothing to do" , launchdAgentPath )
56
56
57
57
}
58
58
}
59
59
60
+ // writeAndLoadPlistFile function will write the plist file, load it, and then exit, because launchd will start a new instance.
61
+ func writeAndLoadPlistFile (launchdAgentPath * paths.Path ) {
62
+ err := writePlistFile (launchdAgentPath )
63
+ if err != nil {
64
+ log .Error (err )
65
+ } else {
66
+ err = loadLaunchdAgent () // this will load the agent: basically starting a new instance
67
+ if err != nil {
68
+ log .Error (err )
69
+ }
70
+ }
71
+ }
72
+
60
73
// writePlistFile function will write the required plist file to launchdAgentPath
61
74
// it will return nil in case of success,
62
75
// it will error in any other case
63
76
func writePlistFile (launchdAgentPath * paths.Path ) error {
77
+ definition , err := getLaunchdAgentDefinition ()
78
+ if err != nil {
79
+ return err
80
+ }
81
+ // we need to create a new launchd plist file
82
+ return launchdAgentPath .WriteFile (definition )
83
+ }
84
+
85
+ // getLaunchdAgentDefinition will return the definition of the new LaunchdAgent
86
+ func getLaunchdAgentDefinition () ([]byte , error ) {
64
87
src , err := os .Executable ()
65
88
66
89
if err != nil {
67
- return err
90
+ return nil , err
68
91
}
69
92
data := struct {
70
93
Program string
@@ -76,9 +99,12 @@ func writePlistFile(launchdAgentPath *paths.Path) error {
76
99
77
100
t := template .Must (template .New ("launchdConfig" ).Parse (string (launchdAgentDefinition )))
78
101
79
- // we need to create a new launchd plist file
80
- plistFile , _ := launchdAgentPath .Create ()
81
- return t .Execute (plistFile , data )
102
+ buf := bytes .NewBuffer (nil )
103
+ err = t .Execute (buf , data )
104
+ if err != nil {
105
+ return nil , err
106
+ }
107
+ return buf .Bytes (), nil
82
108
}
83
109
84
110
// loadLaunchdAgent will use launchctl to load the agent, will return an error if something goes wrong
0 commit comments