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