Skip to content

Commit

Permalink
feat: add "run" command to invoke a compiler
Browse files Browse the repository at this point in the history
this commit adds a "run" command to zvm that allows you to invoke a zig
compiler via its version name. for example: `zvm run 0.14.0 build run --help`
which is useful if you switch around projects a lot and just want to
run a single command without symlinking the version first.
  • Loading branch information
sweetbbak committed Nov 12, 2024
1 parent 233a41c commit ff2d140
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 12 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ like), then ZVM will update the exact executable you've called `upgrade` from.

```sh
curl https://raw.githubusercontent.com/tristanisham/zvm/master/install.sh | bash
# Or
go install -ldflags "-s -w" github.com/tristanisham/zvm@latest
```

<!-- This script will **automatically append** ZVM's required environment variables (see below) to `~/.profile` or `~/.bashrc`. -->
Expand Down
53 changes: 53 additions & 0 deletions cli/meta/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 Tristan Isham. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package meta

import (
"fmt"
"os"
"os/exec"
"strings"
)

// Execute the given Zig command with a specified compiler
func Exec(bin string, cmd []string) error {
// zvm run 0.14.0 build run --help
if bin == "" {
return fmt.Errorf("compiler binary cannot be empty")
}

zig := exec.Command(bin, cmd...)
zig.Stdin, zig.Stdout, zig.Stderr = os.Stdin, os.Stdout, os.Stderr

err := zig.Run()
if err != nil {
if err, ok := err.(*exec.ExitError); ok {
os.Exit(err.ExitCode())
} else {
return fmt.Errorf("Error executing command '%s': %s\n", cmd, err)
}
}

return nil
}

// Execute the given Zig command with a specified compiler
// This is a convenience function that will automatically split a
// command and execute it
func ExecString(cmd string) error {
command := strings.Split(cmd, " ")
if len(command) < 1 {
return fmt.Errorf("No command given")
}

zig := exec.Command(command[0], command[1:]...)
zig.Stdin, zig.Stdout, zig.Stderr = os.Stdin, os.Stdout, os.Stderr

err := zig.Run()
if err != nil {
return fmt.Errorf("Error executing command '%s': %s\n", cmd, err)
}

return nil
}
53 changes: 53 additions & 0 deletions cli/run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
// Copyright 2022 Tristan Isham. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.
package cli

import (
"errors"
"fmt"
"os"
"path/filepath"

"github.com/tristanisham/zvm/cli/meta"
)

// Run the given Zig compiler with the provided arguments
func (z *ZVM) Run(ver string, cmd []string) error {
if err := z.getVersion(ver); err != nil {
if errors.Is(err, os.ErrNotExist) {

fmt.Printf("It looks like %s isn't installed. Would you like to install it first? [y/n]\n", ver)

if getConfirmation() {
if err = z.Install(ver, false); err != nil {
return err
}
} else {
return fmt.Errorf("version %s is not installed", ver)
}
}
}

return z.runBin(ver, cmd)
}

func (z *ZVM) runBin(ver string, cmd []string) error {
// $ZVM_PATH/$VERSION/zig cmd
bin := filepath.Join(z.baseDir, ver, "zig")

// Skip symlink checks, does this Zig binary exist?
stat, err := os.Stat(bin)
if err != nil {
return fmt.Errorf("%w: %s", err, stat.Name())
}

// the logging here really muddies up the output of the Zig compiler
// and adds a lot of noise. For that reason this function exits with
// the zig compilers exit code
if err := meta.Exec(bin, cmd); err != nil {
return err
}

return nil
}
40 changes: 28 additions & 12 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,22 @@ var zvmApp = &opts.App{
}
},
},
{
Name: "run",
Usage: "run a command with the given Zig version",
Args: true,
Flags: []opts.Flag{
&opts.BoolFlag{
Name: "sync",
Usage: "sync your current version of Zig with the repository",
},
},
Action: func(ctx *opts.Context) error {
versionArg := strings.TrimPrefix(ctx.Args().First(), "v")
cmd := ctx.Args().Tail()
return zvm.Run(versionArg, cmd)
},
},
{
Name: "list",
Usage: "list installed Zig versions. Flag `--all` to see remote options",
Expand Down Expand Up @@ -291,18 +307,18 @@ func main() {

// run and report errors
if err := zvmApp.Run(os.Args); err != nil {
// if meta.VERSION == "v0.7.9" && errors.Is(err, cli.ErrInvalidVersionMap) {
// meta.CtaGeneric("Help", `Encountered an issue while trying to install ZLS for Zig 'master'.
// Problem: ZVM v0.7.7 and v0.7.8 may have saved an invalid 'zlsVersionMapUrl' to your settings,
// which causes this error. The latest version, v0.7.9, can fix this issue by using the correct URL.

// To resolve this:
// 1. Open your ZVM settings file: '~/.zvm/settings.json'
// 2. Remove the 'zlsVersionMapUrl' key & value from the file (if present).
// What happens next: ZVM will automatically use the correct version map the next time you run it
// If the issue persists, please double-check your settings and try again, or create a GitHub Issue.`)
// }
// if meta.VERSION == "v0.7.9" && errors.Is(err, cli.ErrInvalidVersionMap) {
// meta.CtaGeneric("Help", `Encountered an issue while trying to install ZLS for Zig 'master'.

// Problem: ZVM v0.7.7 and v0.7.8 may have saved an invalid 'zlsVersionMapUrl' to your settings,
// which causes this error. The latest version, v0.7.9, can fix this issue by using the correct URL.

// To resolve this:
// 1. Open your ZVM settings file: '~/.zvm/settings.json'
// 2. Remove the 'zlsVersionMapUrl' key & value from the file (if present).
// What happens next: ZVM will automatically use the correct version map the next time you run it
// If the issue persists, please double-check your settings and try again, or create a GitHub Issue.`)
// }
meta.CtaFatal(err)
}

Expand Down

0 comments on commit ff2d140

Please sign in to comment.