示例#1
0
文件: project.go 项目: THEY/godo
func watchTask(root string, logName string, handler func(e *watcher.FileEvent)) {
	bufferSize := 2048
	watchr, err := watcher.NewWatcher(bufferSize)
	if err != nil {
		util.Panic("project", "%v\n", err)
	}
	watchr.WatchRecursive(root)
	watchr.ErrorHandler = func(err error) {
		util.Error("project", "%v\n", err)
	}

	// this function will block forever, Ctrl+C to quit app
	var lastHappenedTime int64
	firstTime := true
	for {
		if firstTime {
			util.Info(logName, "watching %s ...\n", root)
			firstTime = false
		}
		event := <-watchr.Event
		//util.Debug("DBG", "watchr.Event %+v\n", event)
		isOlder := event.UnixNano < lastHappenedTime
		lastHappenedTime = event.UnixNano

		if isOlder {
			continue
		}
		handler(event)
	}
}
示例#2
0
文件: project.go 项目: THEY/godo
func (project *Project) mustTask(name string) (*Project, *Task) {
	namespace, taskName := project.namespaceTaskName(name)

	proj := project.Namespace[namespace]
	if proj == nil {
		util.Panic("project", "Could not find project having namespace \"%s\"\n", namespace)
	}

	task := proj.Tasks[taskName]
	if task == nil {
		util.Error("ERR", `"%s" task is not defined`+"\n", name)
		os.Exit(1)
	}
	return proj, task
}
示例#3
0
文件: project.go 项目: THEY/godo
// Task adds a task to the project.
func (project *Project) Task(name string, args ...interface{}) *Task {
	runOnce := false
	if strings.HasSuffix(name, "?") {
		runOnce = true
		name = str.ChompRight(name, "?")
	}
	task := &Task{Name: name, RunOnce: runOnce}

	for _, t := range args {
		switch t := t.(type) {
		default:
			util.Panic("project", "unexpected type %T\n", t) // %T prints whatever type t has
		case Watch:
			task.Watch(t...)
			printDeprecatedWatchWarning(name, t)
		case W:
			task.Watch(t...)
			printDeprecatedWatchWarning(name, t)
		case Dependencies:
			task.Dependencies = t
		case D:
			task.Dependencies = t
		case Debounce:
			task.Debounce(int64(t))
			printDeprecatedDebounceWarning(name, int64(t))
		case func():
			task.Handler = VoidHandlerFunc(t)
		case func() error:
			task.Handler = HandlerFunc(t)
		case func(*Context):
			task.Handler = VoidContextHandlerFunc(t)
		case func(*Context) error:
			task.Handler = ContextHandlerFunc(t)
		case string:
			task.Description(t)
			printDeprecatedDescriptionWarning(name, t)
		}
	}
	project.Tasks[name] = task
	return task
}
示例#4
0
文件: glob.go 项目: THEY/godo
// Glob returns files and dirctories that match patterns. Patterns must use
// slashes, even Windows.
//
// Special chars.
//
//   /**/   - match zero or more directories
//   {a,b}  - match a or b, no spaces
//   *      - match any non-separator char
//   ?      - match a single non-separator char
//   **/    - match any directory, start of pattern only
//   /**    - match any this directory, end of pattern only
//   !      - removes files from resultset, start of pattern only
//
func Glob(patterns []string) ([]*FileAsset, []*RegexpInfo, error) {
	// TODO very inefficient and unintelligent, optimize later

	m := map[string]*FileAsset{}
	regexps := []*RegexpInfo{}

	for _, pattern := range patterns {
		remove := strings.HasPrefix(pattern, "!")
		if remove {
			pattern = pattern[1:]
			if hasMeta(pattern) {
				re := Globexp(pattern)
				regexps = append(regexps, &RegexpInfo{Regexp: re, Negate: true})
				for path := range m {
					if re.MatchString(path) {
						m[path] = nil
					}
				}
			} else {
				path := gpath.Clean(pattern)
				m[path] = nil
			}
		} else {
			if hasMeta(pattern) {
				re := Globexp(pattern)
				regexps = append(regexps, &RegexpInfo{Regexp: re})
				root := patternRoot(pattern)
				if root == "" {
					util.Panic("glob", "Cannot get root from pattern: %s", pattern)
				}
				fileAssets, err := walkFiles(root)
				if err != nil {
					return nil, nil, err
				}

				for _, file := range fileAssets {
					if re.MatchString(file.Path) {
						// TODO closure problem assigning &file
						tmp := file
						m[file.Path] = tmp
					}
				}
			} else {
				path := gpath.Clean(pattern)
				info, err := os.Stat(path)
				if err != nil {
					return nil, nil, err
				}
				fa := &FileAsset{Path: path, FileInfo: info}
				m[path] = fa
			}
		}
	}

	//log.Printf("m %v", m)
	keys := []*FileAsset{}
	for _, it := range m {
		if it != nil {
			keys = append(keys, it)
		}
	}

	return keys, regexps, nil
}