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  // -----------------------------------------------------------------------------