github.com/checksum/notify@v0.0.0-20190119234841-59aa2d88664f/example_fsevents_test.go (about)

     1  // Copyright (c) 2014-2015 The Notify Authors. All rights reserved.
     2  // Use of this source code is governed by the MIT license that can be
     3  // found in the LICENSE file.
     4  
     5  // +build darwin,!kqueue
     6  
     7  package notify_test
     8  
     9  import (
    10  	"log"
    11  
    12  	"github.com/Zillode/notify"
    13  )
    14  
    15  // This example shows how to use FSEvents-specifc event values.
    16  func ExampleWatch_darwin() {
    17  	// Make the channel buffered to ensure no event is dropped. Notify will drop
    18  	// an event if the receiver is not able to keep up the sending pace.
    19  	c := make(chan notify.EventInfo, 1)
    20  
    21  	// Set up a watchpoint listening for FSEvents-specific events within a
    22  	// current working directory. Dispatch each FSEventsChangeOwner and FSEventsMount
    23  	// events separately to c.
    24  	if err := notify.Watch(".", c, notify.FSEventsChangeOwner, notify.FSEventsMount); err != nil {
    25  		log.Fatal(err)
    26  	}
    27  	defer notify.Stop(c)
    28  
    29  	// Block until an event is received.
    30  	switch ei := <-c; ei.Event() {
    31  	case notify.FSEventsChangeOwner:
    32  		log.Println("The owner of", ei.Path(), "has changed.")
    33  	case notify.FSEventsMount:
    34  		log.Println("The path", ei.Path(), "has been mounted.")
    35  	}
    36  }
    37  
    38  // This example shows how to work with EventInfo's underlying FSEvent struct.
    39  // Investigating notify.(*FSEvent).Flags field we are able to say whether
    40  // the event's path is a file or a directory and many more.
    41  func ExampleWatch_darwinDirFileSymlink() {
    42  	var must = func(err error) {
    43  		if err != nil {
    44  			log.Fatal(err)
    45  		}
    46  	}
    47  	var stop = func(c ...chan<- notify.EventInfo) {
    48  		for _, c := range c {
    49  			notify.Stop(c)
    50  		}
    51  	}
    52  
    53  	// Make the channels buffered to ensure no event is dropped. Notify will drop
    54  	// an event if the receiver is not able to keep up the sending pace.
    55  	dir := make(chan notify.EventInfo, 1)
    56  	file := make(chan notify.EventInfo, 1)
    57  	symlink := make(chan notify.EventInfo, 1)
    58  	all := make(chan notify.EventInfo, 1)
    59  
    60  	// Set up a single watchpoint listening for FSEvents-specific events on
    61  	// multiple user-provided channels.
    62  	must(notify.Watch(".", dir, notify.FSEventsIsDir))
    63  	must(notify.Watch(".", file, notify.FSEventsIsFile))
    64  	must(notify.Watch(".", symlink, notify.FSEventsIsSymlink))
    65  	must(notify.Watch(".", all, notify.All))
    66  	defer stop(dir, file, symlink, all)
    67  
    68  	// Block until an event is received.
    69  	select {
    70  	case ei := <-dir:
    71  		log.Println("The directory", ei.Path(), "has changed")
    72  	case ei := <-file:
    73  		log.Println("The file", ei.Path(), "has changed")
    74  	case ei := <-symlink:
    75  		log.Println("The symlink", ei.Path(), "has changed")
    76  	case ei := <-all:
    77  		var kind string
    78  
    79  		// Investigate underlying *notify.FSEvent struct to access more
    80  		// information about the event.
    81  		switch flags := ei.Sys().(*notify.FSEvent).Flags; {
    82  		case flags&notify.FSEventsIsFile != 0:
    83  			kind = "file"
    84  		case flags&notify.FSEventsIsDir != 0:
    85  			kind = "dir"
    86  		case flags&notify.FSEventsIsSymlink != 0:
    87  			kind = "symlink"
    88  		}
    89  
    90  		log.Printf("The %s under path %s has been %sd\n", kind, ei.Path(), ei.Event())
    91  	}
    92  }
    93  
    94  // FSEvents may report multiple filesystem actions with one, coalesced event.
    95  // Notify unscoalesces such event and dispatches series of single events
    96  // back to the user.
    97  //
    98  // This example shows how to coalesce events by investigating notify.(*FSEvent).ID
    99  // field, for the science.
   100  func ExampleWatch_darwinCoalesce() {
   101  	// Make the channels buffered to ensure no event is dropped. Notify will drop
   102  	// an event if the receiver is not able to keep up the sending pace.
   103  	c := make(chan notify.EventInfo, 4)
   104  
   105  	// Set up a watchpoint listetning for events within current working directory.
   106  	// Dispatch all platform-independent separately to c.
   107  	if err := notify.Watch(".", c, notify.All); err != nil {
   108  		log.Fatal(err)
   109  	}
   110  	defer notify.Stop(c)
   111  
   112  	var id uint64
   113  	var coalesced []notify.EventInfo
   114  
   115  	for ei := range c {
   116  		switch n := ei.Sys().(*notify.FSEvent).ID; {
   117  		case id == 0:
   118  			id = n
   119  			coalesced = []notify.EventInfo{ei}
   120  		case id == n:
   121  			coalesced = append(coalesced, ei)
   122  		default:
   123  			log.Printf("FSEvents reported a filesystem action with the following"+
   124  				" coalesced events %v groupped by %d ID\n", coalesced, id)
   125  			return
   126  		}
   127  	}
   128  }