github.com/slspeek/camlistore_namedsearch@v0.0.0-20140519202248-ed6f70f7721a/dev/devcam/appengine.go (about) 1 /* 2 Copyright 2013 The Camlistore Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 // This file adds the "appengine" subcommand to devcam, to run the 18 // development appengine camlistore with dev_appserver.py. 19 20 package main 21 22 import ( 23 "flag" 24 "fmt" 25 "os" 26 "path/filepath" 27 "strconv" 28 29 "camlistore.org/pkg/cmdmain" 30 ) 31 32 type gaeCmd struct { 33 // start of flag vars 34 all bool 35 port string 36 sdk string 37 wipe bool 38 // end of flag vars 39 } 40 41 func init() { 42 cmdmain.RegisterCommand("appengine", func(flags *flag.FlagSet) cmdmain.CommandRunner { 43 cmd := new(gaeCmd) 44 flags.BoolVar(&cmd.all, "all", false, "Listen on all interfaces.") 45 flags.StringVar(&cmd.port, "port", "3179", "Port to listen on.") 46 flags.StringVar(&cmd.sdk, "sdk", "", "The path to the App Engine Go SDK (or a symlink to it).") 47 flags.BoolVar(&cmd.wipe, "wipe", false, "Wipe the blobs on disk and the indexer.") 48 return cmd 49 }) 50 } 51 52 func (c *gaeCmd) Usage() { 53 fmt.Fprintf(cmdmain.Stderr, "Usage: devcam [globalopts] appengine [cmdopts] [other_dev_appserver_opts] \n") 54 } 55 56 func (c *gaeCmd) Describe() string { 57 return "run the App Engine camlistored in dev mode." 58 } 59 60 func (c *gaeCmd) RunCommand(args []string) error { 61 err := c.checkFlags(args) 62 if err != nil { 63 return cmdmain.UsageError(fmt.Sprint(err)) 64 } 65 applicationDir := filepath.Join("server", "appengine") 66 if _, err := os.Stat(applicationDir); err != nil { 67 return fmt.Errorf("Appengine application dir not found at %s", applicationDir) 68 } 69 if err = c.checkSDK(); err != nil { 70 return err 71 } 72 if err = c.mirrorSourceRoot(applicationDir); err != nil { 73 return err 74 } 75 76 devAppServerBin := filepath.Join(c.sdk, "dev_appserver.py") 77 cmdArgs := []string{ 78 "--skip_sdk_update_check", 79 fmt.Sprintf("--port=%s", c.port), 80 } 81 if c.all { 82 cmdArgs = append(cmdArgs, "--host", "0.0.0.0") 83 } 84 if c.wipe { 85 cmdArgs = append(cmdArgs, "--clear_datastore") 86 } 87 cmdArgs = append(cmdArgs, args...) 88 cmdArgs = append(cmdArgs, applicationDir) 89 return runExec(devAppServerBin, cmdArgs, NewCopyEnv()) 90 } 91 92 func (c *gaeCmd) checkFlags(args []string) error { 93 if _, err := strconv.ParseInt(c.port, 0, 0); err != nil { 94 return fmt.Errorf("Invalid -port value: %q", c.port) 95 } 96 return nil 97 } 98 99 func (c *gaeCmd) checkSDK() error { 100 defaultSDK := "appengine-sdk" 101 if c.sdk == "" { 102 c.sdk = defaultSDK 103 } 104 if _, err := os.Stat(c.sdk); err != nil { 105 return fmt.Errorf("App Engine SDK not found. Please specify it with --sdk or:\n$ ln -s /path/to/appengine-go-sdk %s\n\n", defaultSDK) 106 } 107 return nil 108 } 109 110 func (c *gaeCmd) mirrorSourceRoot(gaeAppDir string) error { 111 uiDirs := []string{"server/camlistored/ui", "third_party/closure/lib/closure", "pkg/server"} 112 for _, dir := range uiDirs { 113 oriPath := filepath.Join(camliSrcRoot, filepath.FromSlash(dir)) 114 dstPath := filepath.Join(gaeAppDir, "source_root", filepath.FromSlash(dir)) 115 if err := cpDir(oriPath, dstPath, []string{".go"}); err != nil { 116 return fmt.Errorf("Error while mirroring %s to %s: %v", oriPath, dstPath, err) 117 } 118 } 119 return nil 120 }