~hristoast/wem

d82b985db41554fd07def28f710200616c603511 — Hristos N. Triantafillou 4 months ago a3ba8be
Add an --exec-args arg (#31)
6 files changed, 92 insertions(+), 21 deletions(-)

M cfg/main.go
M cli/args.go
M cli/main.go
M cli/main_test.go
M cmd/completion.go
M cmd/run.go
M cfg/main.go => cfg/main.go +1 -1
@@ 12,7 12,7 @@ import (
)

const WemName = "wem"
const WemVersion = "0.7.1"
const WemVersion = "0.8.0"

type WemConfig struct {
	CacheDir     string

M cli/args.go => cli/args.go +2 -1
@@ 61,7 61,8 @@ type ProtonCmd struct {
type RunCmd struct {
	DryRun      bool     `arg:"--dry-run" help:"Print out a string representing what wem wants to run"`
	EnvName     string   `arg:"positional" help:"The name of the env you wish to run"`
	Exec        []string `arg:"--exec" help:"Run an arbitrary executable with an env's context" placeholder:"CMD ARGS"`
	Exec        string   `arg:"--exec" help:"Run an arbitrary executable with an env's context" placeholder:"CMD"`
	ExecArgs    []string `arg:"--exec-args" help:"Arguments to pass to an executable with --exec" placeholder:"ARGS"`
	SkipInstall bool     `arg:"--skip-install" help:"Skip any configured installation"`
	SkipRun     bool     `arg:"--skip-run" help:"Skip the configured run exe"`
	Winecfg     bool     `arg:"--winecfg" help:"Run winecfg with an env's context"`

M cli/main.go => cli/main.go +3 -2
@@ 173,11 173,12 @@ func run(a args, c *cfg.WemConfig, envName string, installOnly bool) {

		if installOnly {
			err = cmd.Run(c, we, a.Install.DryRun, we.RunOpts.QuietRun,
				false, true, false, false, nil)
				false, true, false, false, "", nil)

		} else {
			err = cmd.Run(c, we, a.Run.DryRun, we.RunOpts.QuietRun,
				a.Run.SkipInstall, a.Run.SkipRun, a.Run.Winecfg, a.Run.Winetricks, a.Run.Exec)
				a.Run.SkipInstall, a.Run.SkipRun, a.Run.Winecfg,
				a.Run.Winetricks, a.Run.Exec, a.Run.ExecArgs)
		}
		if err != nil {
			log.Fatalln(err.Error())

M cli/main_test.go => cli/main_test.go +68 -1
@@ 37,7 37,7 @@ func TestCli(t *testing.T) {
	// The installer.exe and hello-world.exe files are 32-bit Windows executables.
	// See here (or the `test` dir in this repo): https://git.sr.ht/~hristoast/wem-test
	helloWorldExe := fmt.Sprintf("%s/TestPrefixDir/drive_c/wem-test/hello-world.exe", dir)
	installerExe := filepath.Join("..", "test", "installer.exe")
	installerExe, _ := filepath.Abs(filepath.Join("..", "test", "installer.exe"))
	installerDest := filepath.Join(dir, "installer.exe")
	wemExe := filepath.Join("..", "wem")



@@ 366,6 366,73 @@ WinetricksPath = "/usr/bin/winetricks"
		}
	})

	t.Run("Exec in an env (dry-run)", func(t *testing.T) {
		out, err := exe.QuickExe(wemExe, []string{"run", "TEST", "--exec", installerExe, "--exec-args", "C:\\execTest\\Path\\One", "--dry-run"}...)
		if err != nil {
			t.Errorf("Got an error: %s", err)
		}

		if strings.Contains(out, "Disable DXVK") {
			t.Error("got: Disable DXVK message; expected: don't get that message")
		}

		if strings.Contains(out, "Disable VKD3D") {
			t.Error("got: Disable VKD3D message; expected: don't get that message")
		}

		expected := "/usr/bin/wine /home/larry/src/wem/test/installer.exe C:\\execTest\\Path\\One"
		if !strings.Contains(out, expected) {
			t.Errorf("got: missing expected output; expected: %s", expected)
		}
	})

	t.Run("Install an env (again) with exec", func(t *testing.T) {
		expectedExe := fmt.Sprintf("%s/TestPrefixDir/drive_c/execTest/Path/One/hello-world.exe", dir)
		out, err := exe.QuickExe(wemExe, []string{"run", "TEST", "--exec", installerExe, "--exec-args", "C:\\execTest\\Path\\One"}...)

		if err != nil {
			t.Errorf("Got an error: %s", err)
		}

		stat, err := os.Stat(expectedExe)
		if err != nil {
			t.Errorf("Got an error while checking for hello-world.exe's existence: %s", err)
		}
		if stat != nil {
			if stat.IsDir() {
				t.Error("Got an error while checking for hello-world.exe's existence: it is apparently a directory")
			}
		}

		if strings.Contains(out, "Disable DXVK") {
			t.Error("got: Disable DXVK message; expected: don't get that message")
		}

		if strings.Contains(out, "Disable VKD3D") {
			t.Error("got: Disable VKD3D message; expected: don't get that message")
		}

		expected := "Welcome to the WEM Test Installer!"
		if !strings.Contains(out, expected) {
			t.Errorf("got: missing expected output; expected: %s", expected)
		}

		expected = "Installing 'C:\\execTest\\Path\\One\\hello-world.exe' ..."
		if !strings.Contains(out, expected) {
			t.Errorf("got: missing expected output; expected: %s", expected)
		}

		expected = fmt.Sprintf("Install completed! Wrote: %d bytes.", stat.Size())
		if !strings.Contains(out, expected) {
			t.Errorf("got: missing expected output; expected: %s", expected)
		}

		expected = "Exec completed without errors"
		if !strings.Contains(out, expected) {
			t.Errorf("got: missing expected output; expected: %s", expected)
		}
	})

	t.Run("Generate completions", func(t *testing.T) {
		out, err := exe.QuickExe(wemExe, []string{"completion", "--fish", "--bash"}...)
		if err != nil {

M cmd/completion.go => cmd/completion.go +1 -0
@@ 164,6 164,7 @@ complete -c wem -n "__fish_seen_subcommand_from run" -l dry-run -d "Print out a 
complete -c wem -n "__fish_seen_subcommand_from run" -l skip-install -d "Skip any configured installation"
complete -c wem -n "__fish_seen_subcommand_from run" -l skip-run -d "Skip the configured run exe"
complete -c wem -n "__fish_seen_subcommand_from run" -l exec -x -d "Run an arbitrary executable with an env's context"
complete -c wem -n "__fish_seen_subcommand_from run" -l exec-args -x -d "Arguments to pass to an executable with --exec"
complete -c wem -n "__fish_seen_subcommand_from run" -l winecfg -x -d "Run winecfg with an env's context"
complete -c wem -n "__fish_seen_subcommand_from run" -l winetricks -x -d "Run winetricks with an env's context"


M cmd/run.go => cmd/run.go +17 -16
@@ 13,8 13,10 @@ import (
)

func Run(c *cfg.WemConfig, e *env.WineEnv,
	dryRun, quiet, skipInstall, skipRun, winecfg, winetricks bool, exec []string) error {
	if dryRun && exec == nil {
	dryRun, quiet, skipInstall, skipRun, winecfg, winetricks bool, exec string, execArgs []string) error {

	noExec := exec == ""
	if dryRun && noExec {
		var s string
		if skipInstall || (!skipInstall && e.ShouldInstall() && e.IsInstalled()) {
			s = e.ExeString("")


@@ 30,7 32,7 @@ func Run(c *cfg.WemConfig, e *env.WineEnv,
		}
		fmt.Println(s)

	} else if !winecfg && !winetricks && exec == nil {
	} else if !winecfg && !winetricks && noExec {
		ctxes, err := e.ExeCtx(c.CacheDir, skipInstall)
		if err != nil {
			return err


@@ 109,7 111,7 @@ func Run(c *cfg.WemConfig, e *env.WineEnv,
			}
		}

	} else if winecfg && !winetricks && exec == nil {
	} else if winecfg && !winetricks && noExec {
		if dryRun {
			fmt.Println(e.ExeString(e.WineOpts.WineExe + " winecfg"))



@@ 121,7 123,7 @@ func Run(c *cfg.WemConfig, e *env.WineEnv,
			}
		}

	} else if winetricks && !winecfg && exec == nil {
	} else if winetricks && !winecfg && noExec {
		if e.WineOpts.WinetricksPath != "" {
			if dryRun {
				fmt.Println(e.ExeString(e.WineOpts.WinetricksPath))


@@ 138,29 140,28 @@ func Run(c *cfg.WemConfig, e *env.WineEnv,
			return errors.New("no winetricks path is set")
		}

	} else if exec != nil && !winecfg && !winetricks {
		execString, err := e.RenderString(strings.Join(exec, " "))
		if err != nil {
			return err
		}
	} else if !noExec && !winecfg && !winetricks {
		var toExec []string

		toExec := []string{e.WineOpts.WineExe}
		toExec = append(toExec, e.WineOpts.WineExe)
		//TODO: Anything else worth injecting here?
		if e.VirtualDesktop != "" {
			// NOTE: virtual desktop seems to break some applications (e.g. the Fallout 3 Launcher)
			toExec = append(toExec, "explorer", fmt.Sprintf("/desktop=%s", e.VirtualDesktop))
		}
		toExec = append(toExec, execString)

		if dryRun {
			fmt.Println(e.ExeString(strings.Join(toExec, " ")))
		toExec = append(toExec, exec)
		toExec = append(toExec, execArgs...)

		execstr := strings.Join(toExec, " ")
		if dryRun {
			fmt.Println(execstr)
		} else {
			log.Println(fmt.Sprintf("Phase: Exec %s", execString))
			err = withEnvContext(e, toExec[0], strings.Join(toExec[1:], " "), c.CacheDir, fmt.Sprintf("Exec: %s", strings.Join(exec, " ")))
			err := withEnvContext(e, toExec[0], strings.Join(toExec[1:], " "), c.CacheDir, fmt.Sprintf("Exec: %s", execstr))
			if err != nil {
				return err
			}
			log.Println("Exec completed without errors")
		}

	} else {