Example #1
0
func importPathFromPath(root string) string {
	for _, gopath := range filepath.SplitList(build.Default.GOPATH) {
		srcPath := filepath.Join(gopath, "src")
		if strings.HasPrefix(root, srcPath) {
			return filepath.ToSlash(root[len(srcPath)+1:])
		}
	}

	srcPath := filepath.Join(build.Default.GOROOT, "src", "pkg")
	if strings.HasPrefix(root, srcPath) {
		glog.Warning("Code path should be in GOPATH, but is in GOROOT: ", root)
		return filepath.ToSlash(root[len(srcPath)+1:])
	}

	glog.Error("Unexpected! Code path is not in GOPATH: ", root)
	return ""
}
Example #2
0
	// Applications can add custom time formats to this array, and they will be
	// automatically attempted when binding a time.Time.
	TimeFormats = []string{}

	DateFormat     string
	DateTimeFormat string

	IntBinder = Binder{
		Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value {
			if len(val) == 0 {
				return reflect.Zero(typ)
			}
			intValue, err := strconv.ParseInt(val, 10, 64)
			if err != nil {
				glog.Warning(err)
				return reflect.Zero(typ)
			}
			pValue := reflect.New(typ)
			pValue.Elem().SetInt(intValue)
			return pValue.Elem()
		}),
		Unbind: func(output map[string]string, key string, val interface{}) {
			output[key] = fmt.Sprintf("%d", val)
		},
	}

	UintBinder = Binder{
		Bind: ValueBinder(func(val string, typ reflect.Type) reflect.Value {
			if len(val) == 0 {
				return reflect.Zero(typ)
Example #3
0
// Parse the app controllers directory and return a list of the controller types found.
// Returns a CompileError if the parsing fails.
func ProcessSource(roots []string) (*SourceInfo, *revel.Error) {
	var (
		srcInfo      *SourceInfo
		compileError *revel.Error
	)

	for _, root := range roots {
		rootImportPath := importPathFromPath(root)
		if rootImportPath == "" {
			glog.Warning("Skipping code path ", root)
			continue
		}

		// Start walking the directory tree.
		filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
			if err != nil {
				log.Println("Error scanning app source:", err)
				return nil
			}

			if !info.IsDir() || info.Name() == "tmp" {
				return nil
			}

			// Get the import path of the package.
			pkgImportPath := rootImportPath
			if root != path {
				pkgImportPath = rootImportPath + "/" + filepath.ToSlash(path[len(root)+1:])
			}

			// Parse files within the path.
			var pkgs map[string]*ast.Package
			fset := token.NewFileSet()
			pkgs, err = parser.ParseDir(fset, path, func(f os.FileInfo) bool {
				return !f.IsDir() && !strings.HasPrefix(f.Name(), ".") && strings.HasSuffix(f.Name(), ".go")
			}, 0)
			if err != nil {
				if errList, ok := err.(scanner.ErrorList); ok {
					var pos token.Position = errList[0].Pos
					compileError = &revel.Error{
						SourceType:  ".go source",
						Title:       "Go Compilation Error",
						Path:        pos.Filename,
						Description: errList[0].Msg,
						Line:        pos.Line,
						Column:      pos.Column,
						SourceLines: revel.MustReadLines(pos.Filename),
					}
					return compileError
				}
				ast.Print(nil, err)
				log.Fatalf("Failed to parse dir: %s", err)
			}

			// Skip "main" packages.
			delete(pkgs, "main")

			// If there is no code in this directory, skip it.
			if len(pkgs) == 0 {
				return nil
			}

			// There should be only one package in this directory.
			if len(pkgs) > 1 {
				log.Println("Most unexpected! Multiple packages in a single directory:", pkgs)
			}

			var pkg *ast.Package
			for _, v := range pkgs {
				pkg = v
			}

			srcInfo = appendSourceInfo(srcInfo, processPackage(fset, pkgImportPath, path, pkg))
			return nil
		})
	}

	return srcInfo, compileError
}