summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-05-19 05:53:29 -0400
committerRyan Dahl <ry@tinyclouds.org>2018-05-19 05:53:29 -0400
commit258aa565321493fbf6b4325d7b00dbb2058d646a (patch)
treefa315f150950867a07ddd7536f102ddc666ec2d8
parent83f436e175643da6d75e1de3fe905b586012bac2 (diff)
Split up go code into multiple files
-rw-r--r--README.md11
-rw-r--r--deno_dir.go102
-rw-r--r--handlers.go119
-rw-r--r--main.go218
-rw-r--r--main_test.go (renamed from modules_test.go)0
-rw-r--r--util.go16
6 files changed, 247 insertions, 219 deletions
diff --git a/README.md b/README.md
index ddd41cb92..f53bca534 100644
--- a/README.md
+++ b/README.md
@@ -2,5 +2,14 @@
[![Build Status](https://travis-ci.com/propelml/deno.svg?token=eWz4oGVxypBGsz78gdKp&branch=master)](https://travis-ci.com/propelml/deno)
-A simpler JavaScript runtime
+An opinionated JavaScript runtime
+```bash
+make deno # Builds the deno executable
+
+make test # Runs the tests.
+
+make fmt # Formats the code.
+
+make clean # Cleans the build.
+```
diff --git a/deno_dir.go b/deno_dir.go
new file mode 100644
index 000000000..841288936
--- /dev/null
+++ b/deno_dir.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+ "crypto/md5"
+ "encoding/hex"
+ "github.com/ry/v8worker2"
+ "io"
+ "io/ioutil"
+ "net/http"
+ "os"
+ "path"
+ "runtime"
+ "strings"
+)
+
+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)
+ return path.Join(CompileDir, cacheKey+".js")
+}
+
+// Fetches a remoteUrl but also caches it to the localFilename.
+func FetchRemoteSource(remoteUrl string, localFilename string) ([]byte, error) {
+ //println("FetchRemoteSource", remoteUrl)
+ Assert(strings.HasPrefix(localFilename, SrcDir), localFilename)
+ 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)
+}
+
+func LoadOutputCodeCache(filename string, sourceCodeBuf []byte) (outputCode string, err error) {
+ cacheFn := CacheFileName(filename, sourceCodeBuf)
+ outputCodeBuf, err := ioutil.ReadFile(cacheFn)
+ if os.IsNotExist(err) {
+ err = nil // Ignore error if we can't load the cache.
+ } else if err != nil {
+ outputCode = string(outputCodeBuf)
+ }
+ return
+}
+
+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 loadAsset(w *v8worker2.Worker, path string) {
+ data, err := Asset(path)
+ check(err)
+ err = w.Load(path, string(data))
+ check(err)
+}
+
+func createDirs() {
+ DenoDir = path.Join(UserHomeDir(), ".deno")
+ CompileDir = path.Join(DenoDir, "compile")
+ err := os.MkdirAll(CompileDir, 0700)
+ check(err)
+ SrcDir = path.Join(DenoDir, "src")
+ err = os.MkdirAll(SrcDir, 0700)
+ check(err)
+}
diff --git a/handlers.go b/handlers.go
new file mode 100644
index 000000000..5f9470ab1
--- /dev/null
+++ b/handlers.go
@@ -0,0 +1,119 @@
+package main
+
+import (
+ "github.com/golang/protobuf/proto"
+ "io/ioutil"
+ "os"
+ "strings"
+ "time"
+)
+
+const assetPrefix string = "/$asset$/"
+
+func recv(buf []byte) []byte {
+ msg := &Msg{}
+ err := proto.Unmarshal(buf, msg)
+ check(err)
+ switch msg.Payload.(type) {
+ case *Msg_Exit:
+ payload := msg.GetExit()
+ os.Exit(int(payload.Code))
+ case *Msg_SourceCodeFetch:
+ payload := msg.GetSourceCodeFetch()
+ return HandleSourceCodeFetch(payload.ModuleSpecifier, payload.ContainingFile)
+ case *Msg_SourceCodeCache:
+ payload := msg.GetSourceCodeCache()
+ return HandleSourceCodeCache(payload.Filename, payload.SourceCode,
+ payload.OutputCode)
+ case *Msg_TimerStart:
+ payload := msg.GetTimerStart()
+ return HandleTimerStart(payload.Id, payload.Interval, payload.Duration)
+ default:
+ panic("Unexpected message")
+ }
+
+ return nil
+}
+
+func HandleSourceCodeFetch(moduleSpecifier string, containingFile string) (out []byte) {
+ Assert(moduleSpecifier != "", "moduleSpecifier shouldn't be empty")
+ res := &Msg{}
+ var sourceCodeBuf []byte
+ var err error
+
+ defer func() {
+ if err != nil {
+ res.Error = err.Error()
+ }
+ out, err = proto.Marshal(res)
+ check(err)
+ }()
+
+ moduleName, filename, err := ResolveModule(moduleSpecifier, containingFile)
+ if err != nil {
+ return
+ }
+
+ //println("HandleSourceCodeFetch", "moduleSpecifier", moduleSpecifier,
+ // "containingFile", containingFile, "filename", filename)
+
+ if IsRemote(moduleName) {
+ sourceCodeBuf, err = FetchRemoteSource(moduleName, filename)
+ } else if strings.HasPrefix(moduleName, assetPrefix) {
+ f := strings.TrimPrefix(moduleName, assetPrefix)
+ sourceCodeBuf, err = Asset("dist/" + f)
+ } else {
+ Assert(moduleName == filename,
+ "if a module isn't remote, it should have the same filename")
+ sourceCodeBuf, err = ioutil.ReadFile(moduleName)
+ }
+ if err != nil {
+ return
+ }
+
+ outputCode, err := LoadOutputCodeCache(filename, sourceCodeBuf)
+ if err != nil {
+ return
+ }
+
+ res.Payload = &Msg_SourceCodeFetchRes{
+ SourceCodeFetchRes: &SourceCodeFetchResMsg{
+ ModuleName: moduleName,
+ Filename: filename,
+ SourceCode: string(sourceCodeBuf),
+ OutputCode: outputCode,
+ },
+ }
+ return
+}
+
+func HandleSourceCodeCache(filename string, sourceCode string,
+ outputCode string) []byte {
+
+ fn := CacheFileName(filename, []byte(sourceCode))
+ outputCodeBuf := []byte(outputCode)
+ err := ioutil.WriteFile(fn, outputCodeBuf, 0600)
+ res := &Msg{}
+ if err != nil {
+ res.Error = err.Error()
+ }
+ out, err := proto.Marshal(res)
+ check(err)
+ return out
+}
+
+func HandleTimerStart(id int32, interval bool, duration int32) []byte {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ time.Sleep(time.Duration(duration) * time.Millisecond)
+ resChan <- &Msg{
+ Payload: &Msg_TimerReady{
+ TimerReady: &TimerReadyMsg{
+ Id: id,
+ },
+ },
+ }
+ }()
+ return nil
+}
diff --git a/main.go b/main.go
index d299a48ab..1c2a99720 100644
--- a/main.go
+++ b/main.go
@@ -1,22 +1,14 @@
package main
import (
- "crypto/md5"
- "encoding/hex"
"flag"
"fmt"
"github.com/golang/protobuf/proto"
"github.com/ry/v8worker2"
- "io"
- "io/ioutil"
- "net/http"
"net/url"
"os"
"path"
- "runtime"
- "strings"
"sync"
- "time"
)
var flagReload = flag.Bool("reload", false, "Reload cached remote source code.")
@@ -30,61 +22,6 @@ var SrcDir string
var wg sync.WaitGroup
var resChan chan *Msg
-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)
- return path.Join(CompileDir, cacheKey+".js")
-}
-
-func IsRemote(filename string) bool {
- u, err := url.Parse(filename)
- check(err)
- return u.IsAbs()
-}
-
-// Fetches a remoteUrl but also caches it to the localFilename.
-func FetchRemoteSource(remoteUrl string, localFilename string) ([]byte, error) {
- //println("FetchRemoteSource", remoteUrl)
- Assert(strings.HasPrefix(localFilename, SrcDir), localFilename)
- 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)
-}
-
func ResolveModule(moduleSpecifier string, containingFile string) (
moduleName string, filename string, err error) {
moduleUrl, err := url.Parse(moduleSpecifier)
@@ -105,161 +42,6 @@ func ResolveModule(moduleSpecifier string, containingFile string) (
return
}
-const assetPrefix string = "/$asset$/"
-
-func HandleSourceCodeFetch(moduleSpecifier string, containingFile string) (out []byte) {
- Assert(moduleSpecifier != "", "moduleSpecifier shouldn't be empty")
- res := &Msg{}
- var sourceCodeBuf []byte
- var err error
-
- defer func() {
- if err != nil {
- res.Error = err.Error()
- }
- out, err = proto.Marshal(res)
- check(err)
- }()
-
- moduleName, filename, err := ResolveModule(moduleSpecifier, containingFile)
- if err != nil {
- return
- }
-
- //println("HandleSourceCodeFetch", "moduleSpecifier", moduleSpecifier,
- // "containingFile", containingFile, "filename", filename)
-
- if IsRemote(moduleName) {
- sourceCodeBuf, err = FetchRemoteSource(moduleName, filename)
- } else if strings.HasPrefix(moduleName, assetPrefix) {
- f := strings.TrimPrefix(moduleName, assetPrefix)
- sourceCodeBuf, err = Asset("dist/" + f)
- } else {
- Assert(moduleName == filename,
- "if a module isn't remote, it should have the same filename")
- sourceCodeBuf, err = ioutil.ReadFile(moduleName)
- }
- if err != nil {
- return
- }
-
- outputCode, err := LoadOutputCodeCache(filename, sourceCodeBuf)
- if err != nil {
- return
- }
-
- res.Payload = &Msg_SourceCodeFetchRes{
- SourceCodeFetchRes: &SourceCodeFetchResMsg{
- ModuleName: moduleName,
- Filename: filename,
- SourceCode: string(sourceCodeBuf),
- OutputCode: outputCode,
- },
- }
- return
-}
-
-func LoadOutputCodeCache(filename string, sourceCodeBuf []byte) (outputCode string, err error) {
- cacheFn := CacheFileName(filename, sourceCodeBuf)
- outputCodeBuf, err := ioutil.ReadFile(cacheFn)
- if os.IsNotExist(err) {
- err = nil // Ignore error if we can't load the cache.
- } else if err != nil {
- outputCode = string(outputCodeBuf)
- }
- return
-}
-
-func HandleSourceCodeCache(filename string, sourceCode string,
- outputCode string) []byte {
-
- fn := CacheFileName(filename, []byte(sourceCode))
- outputCodeBuf := []byte(outputCode)
- err := ioutil.WriteFile(fn, outputCodeBuf, 0600)
- res := &Msg{}
- if err != nil {
- res.Error = err.Error()
- }
- out, err := proto.Marshal(res)
- check(err)
- return out
-}
-
-func HandleTimerStart(id int32, interval bool, duration int32) []byte {
- wg.Add(1)
- go func() {
- defer wg.Done()
- time.Sleep(time.Duration(duration) * time.Millisecond)
- resChan <- &Msg{
- Payload: &Msg_TimerReady{
- TimerReady: &TimerReadyMsg{
- Id: id,
- },
- },
- }
- }()
- return nil
-}
-
-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 loadAsset(w *v8worker2.Worker, path string) {
- data, err := Asset(path)
- check(err)
- err = w.Load(path, string(data))
- check(err)
-}
-
-func createDirs() {
- DenoDir = path.Join(UserHomeDir(), ".deno")
- CompileDir = path.Join(DenoDir, "compile")
- err := os.MkdirAll(CompileDir, 0700)
- check(err)
- SrcDir = path.Join(DenoDir, "src")
- err = os.MkdirAll(SrcDir, 0700)
- check(err)
-}
-
-func check(e error) {
- if e != nil {
- panic(e)
- }
-}
-
-func recv(buf []byte) []byte {
- msg := &Msg{}
- err := proto.Unmarshal(buf, msg)
- check(err)
- switch msg.Payload.(type) {
- case *Msg_Exit:
- payload := msg.GetExit()
- os.Exit(int(payload.Code))
- case *Msg_SourceCodeFetch:
- payload := msg.GetSourceCodeFetch()
- return HandleSourceCodeFetch(payload.ModuleSpecifier, payload.ContainingFile)
- case *Msg_SourceCodeCache:
- payload := msg.GetSourceCodeCache()
- return HandleSourceCodeCache(payload.Filename, payload.SourceCode,
- payload.OutputCode)
- case *Msg_TimerStart:
- payload := msg.GetTimerStart()
- return HandleTimerStart(payload.Id, payload.Interval, payload.Duration)
- default:
- panic("Unexpected message")
- }
-
- return nil
-}
-
func main() {
flag.Parse()
args := flag.Args()
diff --git a/modules_test.go b/main_test.go
index ac94b5a3c..ac94b5a3c 100644
--- a/modules_test.go
+++ b/main_test.go
diff --git a/util.go b/util.go
index 851ee3475..803260920 100644
--- a/util.go
+++ b/util.go
@@ -1,7 +1,23 @@
package main
+import (
+ "net/url"
+)
+
func Assert(cond bool, msg string) {
if !cond {
panic(msg)
}
}
+
+func IsRemote(filename string) bool {
+ u, err := url.Parse(filename)
+ check(err)
+ return u.IsAbs()
+}
+
+func check(e error) {
+ if e != nil {
+ panic(e)
+ }
+}