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  }