具有等待功能的链接命令

I have the following code which works, I need to execute commands in chain that need to finish before the other command is executed. I do it with the wait command with ugly ifElse and if I need to chain more command it become uglier...is there a better way to write it in go?

    cmd, buf := exec.CommandContext("npm", dir+"/"+path, "install")

    //Wait 
    if err := cmd.Wait(); err != nil {
        log.Printf("executing npm install returned error: %v", err)
    } else {
        log.Println(buf.String())
        gulpCmd, gulpBuf := exec.CommandContext(“gulp”, pdir+"/"+n.path)
   //Wait 
        if err := gulpCmd.Wait(); err != nil {
            log.Printf("error: %v", err)
        } else {
            log.Println(gulpBuf.String())
            pruneCmd, pruneBuf := exec.CommandContext("npm", pdir+"/"+n.path, "prune", "--production")
     //Wait 
            if err := pruneCmd.Wait(); err != nil {
                log.Printf("error: %v", err)
            } else {
                log.Println(pruneBuf.String())
            }

        }

update:

if I try to run this simple program it works and I get message

added 563 packages in 19.218s*

This is the code

cmd := exec.Command("npm", "install")
cmd.Dir = filepath.Join(pdir, n.path)
cmdOutput := &bytes.Buffer{}
cmd.Stdout = cmdOutput
err := cmd.Run()
if err != nil {
    os.Stderr.WriteString(err.Error())
}
fmt.Print(string(cmdOutput.Bytes()))

But If I try like following, I get error and it not able to execute the first command which is npm install, any idea?

cmdParams := [][]string{
    {"npm", filepath.Join(dir,path), "install"},
    {"gulp", filepath.Join(pdir,n.path)},
    {"npm", filepath.Join(pdir, n.path), "prune", "--production"},
}

for _, cmdParam := range cmdParams {
    out, err := exec.Command(cmdParam[0], cmdParam[1:]...).Output()
    if err != nil {
        log.Printf("error running %s: %v
", cmdParam[0], err)
        return
    }
    log.Println(string(out))
}

The error I get is error running npm: exit status 1

update 2

The commands are and should be run one after another, when the first finish just then run the gulp etc, and also I need to provide the output from the commands

1. npm install
2. gulp
3. npm prune 

List your commands in a slice, and use a simple loop to execute all sequentially. And use filepath.Join() to build folders.

Also I'm not sure what package you're using to run the commands, using os/exec we can simplify further the execution of the commands in the loop body. For example Command.Output() runs the command and returns its standard output:

cmdParams := [][]string{
    {filepath.Join(dir,path), "npm", "install"},
    {filepath.Join(pdir,n.path), "gulp"},
    {filepath.Join(pdir, n.path), "npm", "prune", "--production"},
}

for _, cp := range cmdParams {
    log.Printf("Starting %s in folder %s...", cp[1:], cp[0])
    cmd := exec.Command(cp[1], cp[2:]...)
    cmd.Dir = cp[0]
    // Wait to finish, get output:
    out, err := cmd.Output()
    if err != nil {
        log.Printf("Error running %s: %v
", cp[1:], err)
        return
    }
    log.Println("Finished %s, output: %s", cp[1:], out)
}

To avoid ugly if-else you can write code like this:

err := someFunction1()
if err != nil {
  return err
}

err := someFunction2()
if err != nil {
  return err
}

err := someFunction3()
if err != nil {
  return err
}

but you will have ugly (IMHO) multiply return statements