Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

NotFound Error: Failed to spawn 'stty' during 'opengb dev' command execution #394

Open
AliMilani opened this issue Jun 17, 2024 · 2 comments
Labels
bug Something isn't working

Comments

@AliMilani
Copy link

Encountered a NotFound: Failed to spawn 'stty': program not found error when running the opengb dev command. Below are the details of my setup and steps taken:

  • Operating System: Windows 11
  • Docker Version: 26.1.4, build 5650f9b
  • Deno Version: 1.44.2
  • Project Version: Latest (v0.1.5)

Steps to Reproduce:

  1. Initialized the project using opengb init.
  2. Added the friends module.
  3. Executed opengb dev.

Error Trace:

[UNCAUGHT] NotFound: Failed to spawn 'stty': program not found
  at spawnChildInner (ext:runtime/40_process.js:185:17)
  at spawn (ext:runtime/40_process.js:382:10)
  at Command.output (ext:runtime/40_process.js:455:12)
  at watch (https://raw.githubusercontent.com/rivet-gg/opengb/v0.1.1/src/watch/mod.ts:39:6)
  at Command.actionHandler (https://raw.githubusercontent.com/rivet-gg/opengb/v0.1.1/src/cli/commands/dev.ts:22:10)
  at eventLoopTick (ext:core/01_core.js:207:9)
  at async Command.execute (https://deno.land/x/[email protected]/command/command.ts:1948:7)
  at async Command.parseCommand (https://deno.land/x/[email protected]/command/command.ts:1780:14)
  at async https://raw.githubusercontent.com/rivet-gg/opengb/v0.1.1/src/cli/main.ts:51:2

Expected Behavior:
The opengb dev command should execute without errors.

Thank you!

Copy link

linear bot commented Jun 17, 2024

Copy link

greptile-apps bot commented Jun 17, 2024

The error occurs because the 'stty' command is not available on Windows. To resolve this, add a platform check in the watch function in src/watch/mod.ts to avoid calling 'stty' on Windows. Here are the steps:

  1. Open src/watch/mod.ts.
  2. Modify the watch function to include a platform check before running the 'stty' command.
import { abortable } from "./deps.ts";
import { resolve, SEP } from "../deps.ts";
import { Project } from "../project/mod.ts";
import { loadProject } from "../project/project.ts";
import { info, verbose } from "../term/status.ts";
import { InternalError } from "../error/mod.ts";
import { printError } from "../error/mod.ts";
import { colors } from "../term/deps.ts";

export interface WatchOpts {
  disableWatch?: boolean;
  fn: (project: Project, signal: AbortSignal) => Promise<void>;
}

export async function watch(initProject: Project, opts: WatchOpts) {
  if (opts.disableWatch) {
    await opts.fn(initProject, new AbortController().signal);
    return;
  }

  let project = initProject;
  let loadProjectSuccess = true;
  while (true) {
    if (Deno.build.os !== "windows") {
      const sttyOutput = await new Deno.Command("stty", {
        args: ["sane"],
        stdin: "inherit",
        stdout: "inherit",
        stderr: "inherit",
      }).output();
      if (!sttyOutput.success) {
        console.warn("Failed to run `stty sane`. This may cause terminal issues.");
      }
    }

    const { columns } = Deno.consoleSize();
    console.log(`\n${colors.dim("�".repeat(columns))}\n`);

    let fnAbortController: AbortController | undefined;
    if (loadProjectSuccess) {
      fnAbortController = new AbortController();
      abortable(
        wrapWatchFn(project, opts, fnAbortController.signal),
        fnAbortController.signal,
      ).catch((err) => {
        if (err.name != "AbortError") throw err;
      });
    }

    let foundEvent = false;
    const watchPaths = getWatchPaths(project);
    const watcher = Deno.watchFs(watchPaths);
    verbose("Watching", watchPaths.join(", "));
    for await (const event of watcher) {
      const relevantPaths = event.paths.filter(shouldPathTriggerRebuild);
      if (relevantPaths.length > 0) {
        foundEvent = true;
        info("Change detected", `${event.kind}: ${relevantPaths.join(", ")}`);
        break;
      }
    }
    if (!foundEvent) {
      throw new InternalError("Unreachable: watchFs iterator ended");
    }

    try {
      fnAbortController?.abort("Rebuilding project due to file change.");
    } catch (err) {
      if (err.name != "AbortError") throw err;
    }

    try {
      project = await loadProject({ path: project.path });
      loadProjectSuccess = true;
    } catch (err) {
      printError(err);
      loadProjectSuccess = false;
    }
  }
}

async function wrapWatchFn(
  project: Project,
  opts: WatchOpts,
  signal: AbortSignal,
) {
  try {
    await opts.fn(project, signal);
  } catch (err) {
    printError(err);
  }
}

function getWatchPaths(project: Project) {
  const paths: string[] = [
    resolve(project.path, "backend.json"),
  ];
  for (const module of project.modules.values()) {
    if (
      !("local" in module.registry.config) ||
      module.registry.config.local.isExternal
    ) continue;
    paths.push(module.path);
  }
  return paths;
}

function shouldPathTriggerRebuild(path: string) {
  const pathSplit = path.split(SEP);
  if (pathSplit.includes(".opengb") || pathSplit.includes("module.gen.ts")) return false;
  const dbIdx = pathSplit.indexOf("db");
  if (dbIdx != -1 && pathSplit[dbIdx + 1] == "migrations") return false;
  return true;
}

References

/src/cli/commands/dev.ts
/src/watch/mod.ts
/src/cli
/src/utils/postgres_daemon.ts

Ask Greptile

@NathanFlurry NathanFlurry added the bug Something isn't working label Jun 27, 2024 — with Linear
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants