Revel

package revel

const (
    REVEL_IMPORT_PATH = "github.com/robfig/revel"
)

func (r *revelLogs) Write(p []byte) (n int, err error) {
    return r.w.Write([]byte(r.c.Paint(string(p))))
}

var (
    // App details
    AppName    string // e.g. "sample"
    BasePath   string // e.g. "/Users/robfig/gocode/src/corp/sample"
    AppPath    string // e.g. "/Users/robfig/gocode/src/corp/sample/app"
    ViewsPath  string // e.g. "/Users/robfig/gocode/src/corp/sample/app/views"
    ImportPath string // e.g. "corp/sample"
    SourcePath string // e.g. "/Users/robfig/gocode/src"

    Config  *MergedConfig
    RunMode string // Application-defined (by default, "dev" or "prod")
    DevMode bool   // if true, RunMode is a development mode.

    // Revel installation details
    RevelPath string // e.g. "/Users/robfig/gocode/src/revel"

    // Where to look for templates and configuration.
    // Ordered by priority.  (Earlier paths take precedence over later paths.)
    CodePaths     []string
    ConfPaths     []string
    TemplatePaths []string

    Modules []Module

    // Server config.
    //
    // Alert: This is how the app is configured, which may be different from
    // the current process reality.  For example, if the app is configured for
    // port 9000, HttpPort will always be 9000, even though in dev mode it is
    // run on a random port and proxied.
    HttpPort    int    // e.g. 9000
    HttpAddr    string // e.g. "", "127.0.0.1"
    HttpSsl     bool   // e.g. true if using ssl
    HttpSslCert string // e.g. "/path/to/cert.pem"
    HttpSslKey  string // e.g. "/path/to/key.pem"

    // All cookies dropped by the framework begin with this prefix.
    CookiePrefix string

    // Cookie flags
    CookieHttpOnly bool
    CookieSecure   bool

    // Delimiters to use when rendering templates
    TemplateDelims string

    // Loggers
    TRACE = log.New(ioutil.Discard, "TRACE ", log.Ldate|log.Ltime|log.Lshortfile)
    INFO  = log.New(ioutil.Discard, "INFO  ", log.Ldate|log.Ltime|log.Lshortfile)
    WARN  = log.New(ioutil.Discard, "WARN  ", log.Ldate|log.Ltime|log.Lshortfile)
    ERROR = log.New(&error_log, "ERROR ", log.Ldate|log.Ltime|log.Lshortfile)

    Initialized bool
)

// Init initializes Revel -- it provides paths for getting around the app.
//
// Params:
//   mode - the run mode, which determines which app.conf settings are used.
//   importPath - the Go import path of the application.
//   srcPath - the path to the source directory, containing Revel and the app.
//     If not specified (""), then a functioning Go installation is required.
func Init(mode, importPath, srcPath string) {
    // Ignore trailing slashes.
    ImportPath = strings.TrimRight(importPath, "/")
    SourcePath = srcPath
    RunMode = mode

    if runtime.GOOS == "windows" {
        gocolorize.SetPlain(true)
    }

    // If the SourcePath is not specified, find it using build.Import.
    var revelSourcePath string // may be different from the app source path
    if SourcePath == "" {
        revelSourcePath, SourcePath = findSrcPaths(importPath)
    } else {
        // If the SourcePath was specified, assume both Revel and the app are within it.
        SourcePath = path.Clean(SourcePath)
        revelSourcePath = SourcePath
        packaged = true
    }

    RevelPath = path.Join(revelSourcePath, filepath.FromSlash(REVEL_IMPORT_PATH))
    BasePath = path.Join(SourcePath, filepath.FromSlash(importPath))
    AppPath = path.Join(BasePath, "app")
    ViewsPath = path.Join(AppPath, "views")

    CodePaths = []string{AppPath}

    ConfPaths = []string{
        path.Join(BasePath, "conf"),
        path.Join(RevelPath, "conf"),
    }

    TemplatePaths = []string{
        ViewsPath,
        path.Join(RevelPath, "templates"),
    }

    // Load app.conf
    var err error
    Config, err = LoadConfig("app.conf")
    if err != nil || Config == nil {
        log.Fatalln("Failed to load app.conf:", err)
    }
    // Ensure that the selected runmode appears in app.conf.
    // If empty string is passed as the mode, treat it as "DEFAULT"
    if mode == "" {
        mode = config.DEFAULT_SECTION
    }
    if !Config.HasSection(mode) {
        log.Fatalln("app.conf: No mode found:", mode)
    }
    Config.SetSection(mode)

    // Configure properties from app.conf
    DevMode = Config.BoolDefault("mode.dev", false)
    HttpPort = Config.IntDefault("http.port", 9000)
    HttpAddr = Config.StringDefault("http.addr", "")
    HttpSsl = Config.BoolDefault("http.ssl", false)
    HttpSslCert = Config.StringDefault("http.sslcert", "")
    HttpSslKey = Config.StringDefault("http.sslkey", "")
    if HttpSsl {
        if HttpSslCert == "" {
            log.Fatalln("No http.sslcert provided.")
        }
        if HttpSslKey == "" {
            log.Fatalln("No http.sslkey provided.")
        }
    }

    AppName = Config.StringDefault("app.name", "(not set)")
    CookiePrefix = Config.StringDefault("cookie.prefix", "REVEL")
    CookieHttpOnly = Config.BoolDefault("cookie.httponly", false)
    CookieSecure = Config.BoolDefault("cookie.secure", false)
    TemplateDelims = Config.StringDefault("template.delimiters", "")
    if secretStr := Config.StringDefault("app.secret", ""); secretStr != "" {
        secretKey = []byte(secretStr)
    }

    // Configure logging.
    TRACE = getLogger("trace")
    INFO = getLogger("info")
    WARN = getLogger("warn")
    ERROR = getLogger("error")

    loadModules()

    Initialized = true
}

type Module struct {
    Name, ImportPath, Path string
}

// ResolveImportPath returns the filesystem path for the given import path.
// Returns an error if the import path could not be found.
func ResolveImportPath(importPath string) (string, error) {
    if packaged {
        return path.Join(SourcePath, importPath), nil
    }

    modPkg, err := build.Import(importPath, "", build.FindOnly)
    if err != nil {
        return "", err
    }
    return modPkg.Dir, nil
}

// ModuleByName returns the module of the given name, if loaded.
func ModuleByName(name string) (m Module, found bool) {
    for _, module := range Modules {
        if module.Name == name {
            return module, true
        }
    }
    return Module{}, false
}

func CheckInit() {
    if !Initialized {
        panic("Revel has not been initialized!")
    }
}