1515package config
1616
1717import (
18+ "bytes"
1819 // we need this for the ArduinoCreateAgent.plist in this package
1920 _ "embed"
2021 "os"
@@ -38,33 +39,55 @@ func getLaunchdAgentPath() *paths.Path {
3839func InstallPlistFile () {
3940 launchdAgentPath := getLaunchdAgentPath ()
4041 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 )
4451 } 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 )
5255 }
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 )
5656
5757 }
5858}
5959
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+
6073// writePlistFile function will write the required plist file to launchdAgentPath
6174// it will return nil in case of success,
6275// it will error in any other case
6376func 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 ) {
6487 src , err := os .Executable ()
6588
6689 if err != nil {
67- return err
90+ return nil , err
6891 }
6992 data := struct {
7093 Program string
@@ -76,9 +99,12 @@ func writePlistFile(launchdAgentPath *paths.Path) error {
7699
77100 t := template .Must (template .New ("launchdConfig" ).Parse (string (launchdAgentDefinition )))
78101
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
82108}
83109
84110// loadLaunchdAgent will use launchctl to load the agent, will return an error if something goes wrong
0 commit comments