github.com/goplus/gossa@v0.3.25/cmd/internal/run/run.go (about) 1 /* 2 Copyright 2021 The GoPlus Authors (goplus.org) 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 // Package run implements the ``gop run'' command. 18 package run 19 20 import ( 21 "log" 22 "os" 23 "path/filepath" 24 25 "github.com/goplus/gossa" 26 "github.com/goplus/gossa/cmd/internal/base" 27 ) 28 29 // ----------------------------------------------------------------------------- 30 31 // Cmd - gop run 32 var Cmd = &base.Command{ 33 UsageLine: "gossa run <gopSrcDir|gopSrcFile> [arguments]", 34 Short: "Run a Go+ program", 35 } 36 37 var ( 38 flag = &Cmd.Flag 39 flagDumpInstr bool 40 flagTrace bool 41 ) 42 43 func init() { 44 Cmd.Run = runCmd 45 flag.BoolVar(&flagDumpInstr, "dump", false, "dump SSA instruction code") 46 flag.BoolVar(&flagTrace, "trace", false, "trace interpreter code") 47 } 48 49 func runCmd(cmd *base.Command, args []string) { 50 flag.Parse(args) 51 if flag.NArg() < 1 { 52 cmd.Usage(os.Stderr) 53 } 54 args = flag.Args()[1:] 55 path, _ := filepath.Abs(flag.Arg(0)) 56 isDir, err := IsDir(path) 57 if err != nil { 58 log.Fatalln("input arg check failed:", err) 59 } 60 var mode gossa.Mode 61 if flagDumpInstr { 62 mode |= gossa.EnableDumpInstr 63 } 64 if flagTrace { 65 mode |= gossa.EnableTracing 66 } 67 ctx := gossa.NewContext(mode) 68 if isDir { 69 if fnGopBuildDir != nil && containsExt(path, ".gop") { 70 err := fnGopBuildDir(ctx, path) 71 if err != nil { 72 log.Fatalln(err) 73 } 74 } 75 runDir(ctx, path, args) 76 } else { 77 runFile(ctx, path, args) 78 } 79 } 80 81 var fnGopBuildDir func(ctx *gossa.Context, path string) error 82 83 // IsDir checks a target path is dir or not. 84 func IsDir(target string) (bool, error) { 85 fi, err := os.Stat(target) 86 if err != nil { 87 return false, err 88 } 89 return fi.IsDir(), nil 90 } 91 92 func runFile(ctx *gossa.Context, target string, args []string) { 93 dir, file := filepath.Split(target) 94 os.Chdir(dir) 95 exitCode, err := ctx.RunFile(file, nil, args) 96 if err != nil { 97 log.Println(err) 98 } 99 os.Exit(exitCode) 100 } 101 102 func runDir(ctx *gossa.Context, dir string, args []string) { 103 os.Chdir(dir) 104 exitCode, err := ctx.Run(dir, args) 105 if err != nil { 106 log.Println(err) 107 } 108 os.Exit(exitCode) 109 } 110 111 func containsExt(srcDir string, ext string) bool { 112 if f, err := os.Open(srcDir); err == nil { 113 defer f.Close() 114 fis, _ := f.Readdir(-1) 115 for _, fi := range fis { 116 if !fi.IsDir() && filepath.Ext(fi.Name()) == ext { 117 return true 118 } 119 } 120 } 121 return false 122 } 123 124 // -----------------------------------------------------------------------------