denox icon indicating copy to clipboard operation
denox copied to clipboard

Support for inline arbitrary script execution

Open wattry opened this issue 4 years ago • 1 comments

Issue Type

  • [ ] Bug Report
  • [x] Feature Request
  • [ ] Other

Summary

Firstly, this is a great package, it's great to see deno being used in the wild. Something I've missed (moving from Node) is the ability to execute inline scripts.

Several of our projects use scripts to build, package and deploy using yarn ~~(or npm)~~. This allows developers to store complex scripts and execute them when they aren't directly related to the src code but perform repetitive tasks.

These tasks would otherwise have to be remembered or stored in the project. I have resorted to creating a ./scripts directory in the project root. However, this feels like unnecessary noise for administrative scripts

My proposal would be to introduce the ability to either execute a cmd or a file by checking the file or cmd flag on the deno_workspace file.

Possible Solutions

There are several requirements for this:

  1. There would have to be a check to see if the user was trying to execute a cmd/script or a file script in the _runScript.
  2. We would need to replace whatever env variables were being placed into the script (as this is a common occurrence).
  3. It would have to work for both deno inline script execution and some arbitrary script execution.

If I have forgotten anything let me know. I have put together a pull request and added the relevant tests. This is more of a placeholder until the env var issue has been introduced. I think there might be an opportunity to create further test penetration on the run.ts file.

async function _runScript(
  scriptName: string,
  args: string[],
): Promise<{ code: number }> {
  const workspace = await loadDenoWorkspace();

  const workspaceScript = workspace.scripts[scriptName];
  const workspaceGlobal = workspace?.globals || {};

  if (workspaceScript === undefined) {
    throw new ScriptNotFoundError(scriptName);
  }

  return workspaceScript.file
    ? await _runDenoFile(workspaceScript, workspaceGlobal, args)
    : await _runInlineScript(workspaceScript, args);
}

async function _runInlineScript(
  workspaceScript: WorkspaceScript,
  workspaceGlobal: WorkspaceOptions,
  args: string[],
): Promise<{ code: number }> {
  const cmd: any[] = workspaceScript.cmd?.split(' ').concat(args) || [];
  const [mainScript]: string = cmd;

  // If the first argument is deno then we want the deno options.
  if (mainScript === 'deno') {
    const denoOptions = await _getDenoOptions(workspaceScript, workspaceGlobal);

    cmd.concat(denoOptions);
  }

  const process = Deno.run({
    cmd
  });

  const { code } = await process.status();

  return { code };
}

Again, thanks for the great project.

wattry avatar Jun 15 '20 19:06 wattry

This is a great addition to DenoX I commented on the PR

BentoumiTech avatar Aug 11 '20 12:08 BentoumiTech