func build(sourcepath string) error { goBuild := utils.CommandBuilder("go", "build", sourcepath) goBuild.Dir = workingDir goBuild.Stdout = os.Stdout goBuild.Stderr = os.Stderr if err := goBuild.Run(); err != nil { ferr := errBuild.Format(sourcepath, err.Error()) printer.Dangerf(ferr.Error()) return ferr } return nil }
func run(executablePath string, stdout bool) (*utils.Cmd, error) { runCmd := utils.CommandBuilder("." + utils.PathSeparator + executablePath) runCmd.Dir = workingDir if stdout { runCmd.Stdout = os.Stdout } runCmd.Stderr = os.Stderr if err := runCmd.Start(); err != nil { ferr := errRun.Format(executablePath, err.Error()) printer.Dangerf(ferr.Error()) return nil, ferr } return runCmd, nil }
func run(executablePath string) (*utils.Cmd, error) { runCmd := utils.CommandBuilder("." + utils.PathSeparator + executablePath) if times >= 1 { runCmd.AppendArguments("-s") //-s to skip the banner after the first time } runCmd.Dir = workingDir runCmd.Stderr = os.Stderr runCmd.Stdout = os.Stdout runCmd.Stderr = os.Stderr if err := runCmd.Start(); err != nil { ferr := errRun.Format(executablePath, err.Error()) printer.Dangerf(ferr.Error()) return nil, ferr } times++ return runCmd, nil }
// start starts the job func (e *Plugin) start() { if e.config.Username == "" || e.config.Password == "" { e.logger.Println("Error before running alm-tools. You have to set username & password for security reasons, otherwise this plugin won't run.") return } if !npm.Exists("alm/bin/alm") { e.logger.Println("Installing alm-tools, please wait...") res := npm.Install("alm") if res.Error != nil { e.logger.Print(res.Error.Error()) return } e.logger.Print(res.Message) } cmd := utils.CommandBuilder("node", npm.Abs("alm/src/server.js")) cmd.AppendArguments("-a", e.config.Username+":"+e.config.Password, "-h", e.config.Host, "-t", strconv.Itoa(e.config.Port), "-d", e.config.WorkingDir[0:len(e.config.WorkingDir)-1]) // for auto-start in the browser: cmd.AppendArguments("-o") if e.keyfile != "" && e.certfile != "" { cmd.AppendArguments("--httpskey", e.keyfile, "--httpscert", e.certfile) } //For debug only: //cmd.Stdout = os.Stdout //cmd.Stderr = os.Stderr //os.Stdin = os.Stdin err := cmd.Start() if err != nil { e.logger.Println("Error while running alm-tools. Trace: " + err.Error()) return } //we lose the internal error handling but ok... e.logger.Printf("Editor is running at %s:%d | %s", e.config.Host, e.config.Port, e.config.WorkingDir) }
func create(flags cli.Flags) (err error) { targetDir, err := filepath.Abs(flags.String("dir")) if err != nil { panic(err) } if !isValidInstallDir(targetDir) { printer.Dangerf("\nPlease make sure you are targeting a directory inside $GOPATH, type iris -h for help.") return } if !utils.DirectoryExists(packagesInstallDir) || !flags.Bool("offline") { // install/update go dependencies at the same time downloading the zip from the github iris-contrib assets finish := make(chan bool) go func() { go func() { for _, source := range packagesDependencies { gogetCmd := utils.CommandBuilder("go", "get", source) if msg, err := gogetCmd.CombinedOutput(); err != nil { panic("Unable to go get " + source + " please make sure you're connected to the internet.\nSolution: Remove your $GOPATH/src/github.com/iris-contrib/middleware folder and re-run the iris create\nReason:\n" + string(msg)) } } finish <- true }() downloadPackages() <-finish }() <-finish close(finish) } createPackage(flags.String("type"), targetDir) return }
func runAndWatch(flags cli.Flags) error { if len(os.Args) <= 2 { err := errInvalidArgs.Format(strings.Join(os.Args, ",")) printer.Dangerf(err.Error()) return err } isWindows := runtime.GOOS == "windows" programPath := "" executablePath := "" filenameCh := make(chan string) if len(os.Args) > 2 { // iris run main.go programPath = os.Args[2] if programPath[len(programPath)-1] == '/' { programPath = programPath[0 : len(programPath)-1] } if filepath.Ext(programPath) != goExt { return errInvalidExt.Format(programPath) } executablePath = programPath[:len(programPath)-3] if isWindows { executablePath += ".exe" } } // here(below), we don't return the error because the -help command doesn't help the user for these errors. // run the file watcher before all, because the user maybe has a go syntax error before the first run utils.WatchDirectoryChanges(workingDir, func(fname string) { //remove the working dir from the fname path, printer should only print the relative changed file ( from the project's path) fname = fname[len(workingDir)+1:] if (filepath.Ext(fname) == goExt) || (!isWindows && strings.Contains(fname, goExt)) { // on !windows it sends a .gooutput_RANDOM_STRINGHERE, Note that: we do contains instead of HasPrefix filenameCh <- fname } }, printer) if err := build(programPath); err != nil { return err } runCmd, err := run(executablePath, true) if err != nil { return err } defer func() { printer.Dangerf("") printer.Panic(errUnexpected) }() var times uint32 = 1 for { select { case fname := <-filenameCh: { // it's not a warning but I like to use purple color for this message if !isWindows { fname = " " // we don't want to print the ".gooutput..." so dont print anything as a name } printer.Infof("\n[OP: %d] File %s changed, reloading...", atomic.LoadUint32(×), fname) //kill the prev run err := runCmd.Process.Kill() if err == nil { _, err = runCmd.Process.Wait() } else { // force kill, sometimes runCmd.Process.Kill or Signal(os.Kill) doesn't kills if isWindows { err = utils.CommandBuilder("taskkill", "/F", "/T", "/PID", strconv.Itoa(runCmd.Process.Pid)).Run() } else { err = utils.CommandBuilder("kill", "-INT", "-"+strconv.Itoa(runCmd.Process.Pid)).Run() } } err = build(programPath) if err != nil { printer.Warningf(err.Error()) } else { if runCmd, err = run(executablePath, false); err != nil { printer.Warningf(err.Error()) } else { // we did .Start, but it should be fast so no need to add a sleeper printer.Successf("ready!") atomic.AddUint32(×, 1) } } } } } }
func createPackage(packageName string, targetDir string) error { installTo := targetDir // os.Getenv("GOPATH") + utils.PathSeparator + "src" + utils.PathSeparator + targetDir packageDir := packagesInstallDir + utils.PathSeparator + packageName err := utils.CopyDir(packageDir, installTo) if err != nil { printer.Dangerf("\nProblem while copying the %s package to the %s. Trace: %s", packageName, installTo, err.Error()) return err } // now replace main.go's 'github.com/iris-contrib/iris-command-assets/basic/' with targetDir // hardcode all that, we don't have anything special and neither will do targetDir = strings.Replace(targetDir, "\\", "/", -1) // for any case mainFile := installTo + utils.PathSeparator + "backend" + utils.PathSeparator + "main.go" input, err := ioutil.ReadFile(mainFile) if err != nil { printer.Warningf("Error while preparing main file: %#v", err) } output := strings.Replace(string(input), "github.com/iris-contrib/iris-command-assets/"+packageName+"/", filepath.Base(targetDir)+"/", -1) err = ioutil.WriteFile(mainFile, []byte(output), 0777) if err != nil { printer.Warningf("Error while preparing main file: %#v", err) } printer.Infof("%s package was installed successfully [%s]", packageName, installTo) // build & run the server // go build buildCmd := utils.CommandBuilder("go", "build") if installTo[len(installTo)-1] != os.PathSeparator || installTo[len(installTo)-1] != '/' { installTo += utils.PathSeparator } buildCmd.Dir = installTo + "backend" buildCmd.Stderr = os.Stderr err = buildCmd.Start() if err != nil { printer.Warningf("\n Failed to build the %s package. Trace: %s", packageName, err.Error()) } buildCmd.Wait() print("\n\n") // run backend/backend(.exe) executable := "backend" if runtime.GOOS == "windows" { executable += ".exe" } runCmd := utils.CommandBuilder("." + utils.PathSeparator + executable) runCmd.Dir = buildCmd.Dir runCmd.Stdout = os.Stdout runCmd.Stderr = os.Stderr err = runCmd.Start() if err != nil { printer.Warningf("\n Failed to run the %s package. Trace: %s", packageName, err.Error()) } runCmd.Wait() return err }
func (t *Plugin) start() { defaultCompilerArgs := t.options.Tsconfig.CompilerArgs() //these will be used if no .tsconfig found. if t.hasTypescriptFiles() { //Can't check if permission denied returns always exists = true.... //typescriptModule := out + string(os.PathSeparator) + "typescript" + string(os.PathSeparator) + "bin" if !npm.Exists(t.options.Bin) { t.logger.Println("Installing typescript, please wait...") res := npm.Install("typescript") if res.Error != nil { t.logger.Print(res.Error.Error()) return } t.logger.Print(res.Message) } projects := t.getTypescriptProjects() if len(projects) > 0 { watchedProjects := 0 //typescript project (.tsconfig) found for _, project := range projects { cmd := utils.CommandBuilder("node", t.options.Bin, "-p", project[0:strings.LastIndex(project, utils.PathSeparator)]) //remove the /tsconfig.json) projectConfig := FromFile(project) if projectConfig.CompilerOptions.Watch { watchedProjects++ // if has watch : true then we have to wrap the command to a goroutine (I don't want to use the .Start here) go func() { _, err := cmd.Output() if err != nil { t.logger.Println(err.Error()) return } }() } else { _, err := cmd.Output() if err != nil { t.logger.Println(err.Error()) return } } } t.logger.Printf("%d Typescript project(s) compiled ( %d monitored by a background file watcher ) ", len(projects), watchedProjects) } else { //search for standalone typescript (.ts) files and compile them files := t.getTypescriptFiles() if len(files) > 0 { watchedFiles := 0 if t.options.Tsconfig.CompilerOptions.Watch { watchedFiles = len(files) } //it must be always > 0 if we came here, because of if hasTypescriptFiles == true. for _, file := range files { cmd := utils.CommandBuilder("node", t.options.Bin) cmd.AppendArguments(defaultCompilerArgs...) cmd.AppendArguments(file) _, err := cmd.Output() cmd.Args = cmd.Args[0 : len(cmd.Args)-1] //remove the last, which is the file if err != nil { t.logger.Println(err.Error()) return } } t.logger.Printf("%d Typescript file(s) compiled ( %d monitored by a background file watcher )", len(files), watchedFiles) } } //editor activation if len(projects) == 1 && t.options.Editor != nil { dir := projects[0][0:strings.LastIndex(projects[0], utils.PathSeparator)] t.options.Editor.Dir(dir) t.pluginContainer.Add(t.options.Editor) } } }