2018-05-19 05:53:29 -04:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"crypto/md5"
|
|
|
|
"encoding/hex"
|
2018-05-25 12:15:48 -04:00
|
|
|
"flag"
|
2018-05-19 05:53:29 -04:00
|
|
|
"io"
|
|
|
|
"io/ioutil"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"path"
|
|
|
|
"runtime"
|
|
|
|
"strings"
|
|
|
|
)
|
|
|
|
|
2018-05-25 12:15:48 -04:00
|
|
|
var flagCacheDir = flag.String("cachedir", "",
|
|
|
|
"Where to cache compilation artifacts. Default: ~/.deno")
|
|
|
|
|
2018-05-24 10:25:38 -04:00
|
|
|
var DenoDir string
|
|
|
|
var CacheDir string
|
|
|
|
var SrcDir string
|
|
|
|
|
2018-05-19 05:53:29 -04:00
|
|
|
func SourceCodeHash(filename string, sourceCodeBuf []byte) string {
|
|
|
|
h := md5.New()
|
|
|
|
h.Write([]byte(filename))
|
|
|
|
h.Write(sourceCodeBuf)
|
|
|
|
return hex.EncodeToString(h.Sum(nil))
|
|
|
|
}
|
|
|
|
|
|
|
|
func CacheFileName(filename string, sourceCodeBuf []byte) string {
|
|
|
|
cacheKey := SourceCodeHash(filename, sourceCodeBuf)
|
2018-05-24 10:25:38 -04:00
|
|
|
return path.Join(CacheDir, cacheKey+".js")
|
2018-05-19 05:53:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
// Fetches a remoteUrl but also caches it to the localFilename.
|
|
|
|
func FetchRemoteSource(remoteUrl string, localFilename string) ([]byte, error) {
|
2018-05-28 09:48:33 -04:00
|
|
|
logDebug("FetchRemoteSource %s %s", remoteUrl, localFilename)
|
|
|
|
assert(strings.HasPrefix(localFilename, SrcDir),
|
|
|
|
"Expected filename to start with SrcDir: "+localFilename)
|
2018-05-19 05:53:29 -04:00
|
|
|
var sourceReader io.Reader
|
|
|
|
|
|
|
|
file, err := os.Open(localFilename)
|
|
|
|
if *flagReload || os.IsNotExist(err) {
|
|
|
|
// Fetch from HTTP.
|
|
|
|
println("Downloading", remoteUrl)
|
|
|
|
res, err := http.Get(remoteUrl)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
defer res.Body.Close()
|
|
|
|
|
|
|
|
err = os.MkdirAll(path.Dir(localFilename), 0700)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Write to to file. Need to reopen it for writing.
|
|
|
|
file, err = os.OpenFile(localFilename, os.O_RDWR|os.O_CREATE, 0700)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
sourceReader = io.TeeReader(res.Body, file) // Fancy!
|
|
|
|
|
|
|
|
} else if err != nil {
|
|
|
|
return nil, err
|
|
|
|
} else {
|
|
|
|
sourceReader = file
|
|
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
return ioutil.ReadAll(sourceReader)
|
|
|
|
}
|
|
|
|
|
2018-05-22 12:43:20 -04:00
|
|
|
func LoadOutputCodeCache(filename string, sourceCodeBuf []byte) (
|
|
|
|
outputCode string, err error) {
|
2018-05-19 05:53:29 -04:00
|
|
|
cacheFn := CacheFileName(filename, sourceCodeBuf)
|
|
|
|
outputCodeBuf, err := ioutil.ReadFile(cacheFn)
|
|
|
|
if os.IsNotExist(err) {
|
2018-05-22 12:43:20 -04:00
|
|
|
// Ignore error if we can't find the cache file.
|
|
|
|
err = nil
|
|
|
|
} else if err == nil {
|
2018-05-19 05:53:29 -04:00
|
|
|
outputCode = string(outputCodeBuf)
|
|
|
|
}
|
2018-05-22 12:43:20 -04:00
|
|
|
return outputCode, err
|
2018-05-19 05:53:29 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func UserHomeDir() string {
|
|
|
|
if runtime.GOOS == "windows" {
|
|
|
|
home := os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
|
|
|
|
if home == "" {
|
|
|
|
home = os.Getenv("USERPROFILE")
|
|
|
|
}
|
|
|
|
return home
|
|
|
|
}
|
|
|
|
return os.Getenv("HOME")
|
|
|
|
}
|
|
|
|
|
|
|
|
func createDirs() {
|
2018-05-25 12:15:48 -04:00
|
|
|
if *flagCacheDir == "" {
|
2018-05-24 10:34:05 -04:00
|
|
|
DenoDir = path.Join(UserHomeDir(), ".deno")
|
|
|
|
} else {
|
2018-05-25 12:15:48 -04:00
|
|
|
DenoDir = *flagCacheDir
|
2018-05-24 10:34:05 -04:00
|
|
|
}
|
2018-05-24 10:25:38 -04:00
|
|
|
CacheDir = path.Join(DenoDir, "cache")
|
|
|
|
err := os.MkdirAll(CacheDir, 0700)
|
2018-05-19 05:53:29 -04:00
|
|
|
check(err)
|
|
|
|
SrcDir = path.Join(DenoDir, "src")
|
|
|
|
err = os.MkdirAll(SrcDir, 0700)
|
|
|
|
check(err)
|
|
|
|
}
|