func startGitDaemon(absolutePath string) error { daemonSentinel := path.Join(absolutePath, ".git", "git-daemon-export-ok") if _, err := os.Stat(daemonSentinel); os.IsNotExist(err) { _, err := os.Create(daemonSentinel) if err != nil { log.Fatalf("Unable to set up git daemon") } } cmd := exec.Command("git", "daemon", "--reuseaddr", fmt.Sprintf("--base-path=%s/..", absolutePath), absolutePath) err := cmd.Start() return err }
func main() { // Start changes handler var ( username = flag.String("user", "", "Username to report when sending changes to the network") groupIP = flag.String("ip", gitsync.IP4MulticastAddr.IP.String(), "Multicast IP to connect to") groupPort = flag.Int("port", gitsync.IP4MulticastAddr.Port, "Port to use for network IO") logLevel = flag.String("loglevel", "info", "Lowest log level to emit. Can be one of debug, info, warning, error.") logSocket = flag.String("logsocket", "", "proto://address:port target to send logs to") logFile = flag.String("logfile", "", "path to file to log to") webPort = flag.Int("webport", 0, "Port for local webserver. Off by default") ) flag.Parse() if len(flag.Args()) == 0 { fatalf("No Git directory supplied") } if err := setupLogging(*logLevel, *logSocket, *logFile); err != nil { fatalf("Cannot setup logging: %s", err) } log.Info("Starting up") defer log.Info("Exiting") var ( err error dirName = flag.Args()[0] // directories to watch userId string // username groupAddr *net.UDPAddr // network address to connect to // channels to move change messages around remoteChanges = make(chan gitsync.GitChange, 128) toRemoteChanges = make(chan gitsync.GitChange, 128) ) dirName = util.AbsPath(dirName) // get the user's name if *username != "" { userId = *username } else if user, err := user.Current(); err == nil { userId = user.Username } else { fatalf("Cannot get username: %v", err) } if groupAddr, err = net.ResolveUDPAddr("udp", fmt.Sprintf("%s:%d", *groupIP, *groupPort)); err != nil { fatalf("Cannot resolve address %v:%v: %v", *groupIP, *groupPort, err) } // start directory poller repo, err := gitsync.NewCliRepo(userId, dirName) if err != nil { fatalf("Cannot open repo: %s", err) } if err = startGitDaemon(dirName); err != nil { log.Fatalf("Unable to start git daemon") } go gitsync.PollDirectory(log.Global, dirName, repo, toRemoteChanges, 1*time.Second) go gitsync.NetIO(log.Global, repo, groupAddr, remoteChanges, toRemoteChanges) go ReceiveChanges(remoteChanges, uint16(*webPort), repo) s := make(chan os.Signal, 1) signal.Notify(s, os.Kill, os.Interrupt, syscall.SIGUSR1) for { c := <-s cleanup(dirName) if (c == os.Kill) || (c == os.Interrupt) { break } } }
// fatalf logs a fatal error and exits func fatalf(format string, args ...interface{}) { fmt.Fprintf(os.Stderr, format+"\n", args...) log.Fatalf(format, args...) }