@@ -39,6 +39,7 @@ Advanced options:
3939 -s, --signal restart signal name or number (default SIGINT)
4040 -v, --verbose log more info; set twice to log lower level debug info
4141 -p, --print-changes print change events to stdout without running a command
42+ --wait wait for one change, then exit without running a command
4243` )
4344}
4445
@@ -116,6 +117,10 @@ func parseConfig(args []string) (*Config, error) {
116117 cfg .PrintChanges = true
117118 continue
118119 }
120+ if arg == "--wait" {
121+ cfg .Wait = true
122+ continue
123+ }
119124
120125 // Parse string flags
121126 for _ , spec := range []struct {
@@ -264,8 +269,11 @@ func parseConfig(args []string) (*Config, error) {
264269 }
265270 cfg .notifySignal = s
266271 }
267- if cfg .PrintChanges {
272+ if cfg .PrintChanges || cfg . Wait {
268273 if len (cfg .Command ) > 0 {
274+ if cfg .Wait {
275+ return nil , fmt .Errorf ("--wait cannot be used with a command" )
276+ }
269277 return nil , fmt .Errorf ("--print-changes cannot be used with a command" )
270278 }
271279 } else {
@@ -667,7 +675,9 @@ func (g *godemon) Start() error {
667675 defer func () {
668676 debugf ("Removing file watchers" )
669677 w .Close ()
670- select {} // Wait for shutdown to finish.
678+ if ! g .cfg .Wait {
679+ select {} // Wait for shutdown to finish.
680+ }
671681 }()
672682 g .w = w
673683
@@ -695,7 +705,9 @@ func (g *godemon) Start() error {
695705 notifyf ("Exiting due to --dry-run flag." )
696706 }
697707
698- if g .cfg .PrintChanges {
708+ if g .cfg .Wait {
709+ g .waitForChange (addCh )
710+ } else if g .cfg .PrintChanges {
699711 // In print-changes mode, just print events to stdout without running a command.
700712 g .handlePrintChanges (addCh , shutdownCh )
701713 } else {
@@ -852,30 +864,36 @@ func (g *godemon) handleAdds(addCh chan string) {
852864 }
853865}
854866
867+ func (g * godemon ) handleChange (addCh chan <- string , event fsEvent ) bool {
868+ if g .shouldIgnore (event .Path ) {
869+ infof ("Ignoring event: %s %q" , event .Op , event .Path )
870+ return false
871+ }
872+ infof ("Got event: %s %q" , event .Op , event .Path )
873+
874+ if g .cfg .Lockfile != nil && * g .cfg .Lockfile != "" {
875+ if err := waitForLockfileRemoval (* g .cfg .Lockfile ); err != nil {
876+ warnf ("waitForLockfileRemoval failed: %s" , err )
877+ }
878+ }
879+
880+ // When creating new dirs, add them to the watch list (recursive watchers
881+ // cover newly created dirs automatically).
882+ if ! g .w .Recursive () && event .Op & opCreate != 0 && isDir (event .Path ) {
883+ addCh <- event .Path
884+ }
885+ return true
886+ }
887+
855888func (g * godemon ) handleEvents (addCh chan <- string , restartCh chan <- struct {}, shutdownCh <- chan struct {}) {
856889 for {
857890 select {
858891 case err := <- g .w .Errors ():
859892 warnf ("%s" , err )
860893 case event := <- g .w .Events ():
861- if g .shouldIgnore (event .Path ) {
862- infof ("Ignoring event: %s %q" , event .Op , event .Path )
863- continue
864- }
865- infof ("Got event: %s %q" , event .Op , event .Path )
866-
867- if g .cfg .Lockfile != nil && * g .cfg .Lockfile != "" {
868- if err := waitForLockfileRemoval (* g .cfg .Lockfile ); err != nil {
869- warnf ("waitForLockfileRemoval failed: %s" , err )
870- }
894+ if g .handleChange (addCh , event ) {
895+ restartCh <- struct {}{}
871896 }
872-
873- // When creating new dirs, add them to the watch list (recursive
874- // watchers cover newly created dirs automatically).
875- if ! g .w .Recursive () && event .Op & opCreate != 0 && isDir (event .Path ) {
876- addCh <- event .Path
877- }
878- restartCh <- struct {}{}
879897 case <- shutdownCh :
880898 debugf ("handleEvents: got shutdown signal" )
881899 return
@@ -897,26 +915,33 @@ func (g *godemon) handlePrintChanges(addCh chan<- string, shutdownCh <-chan stru
897915 case err := <- g .w .Errors ():
898916 warnf ("%s" , err )
899917 case event := <- g .w .Events ():
900- if g .shouldIgnore (event .Path ) {
901- infof ("Ignoring event: %s %q" , event .Op , event .Path )
902- continue
903- }
904- if ! isQuiet () {
918+ if g .handleChange (addCh , event ) && ! isQuiet () {
905919 // Print the change event to stdout
906920 fmt .Printf ("%s %s\n " , event .Op , event .Path )
907921 }
908- // When creating new dirs, add them to the watch list (recursive
909- // watchers cover newly created dirs automatically).
910- if ! g .w .Recursive () && event .Op & opCreate != 0 && isDir (event .Path ) {
911- addCh <- event .Path
912- }
913922 case <- shutdownCh :
914923 debugf ("handlePrintChanges: got shutdown signal" )
915924 return
916925 }
917926 }
918927}
919928
929+ func (g * godemon ) waitForChange (addCh chan <- string ) {
930+ for {
931+ select {
932+ case err := <- g .w .Errors ():
933+ warnf ("%s" , err )
934+ case event := <- g .w .Events ():
935+ if g .handleChange (addCh , event ) {
936+ if g .cfg .PrintChanges && ! isQuiet () {
937+ fmt .Printf ("%s %s\n " , event .Op , event .Path )
938+ }
939+ return
940+ }
941+ }
942+ }
943+ }
944+
920945func waitForLockfileRemoval (path string ) error {
921946 debugf ("Waiting for removal of lockfile %s" , path )
922947
0 commit comments