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

Inline Scripts #89

Open
thejmazz opened this issue Oct 8, 2017 · 1 comment
Open

Inline Scripts #89

thejmazz opened this issue Oct 8, 2017 · 1 comment

Comments

@thejmazz
Copy link
Member

thejmazz commented Oct 8, 2017

Due to the way we parse a string into a child process it may be the case that certain operations (e.g., a bash for/while read loop) may not run.

It would be nice to use ES6 tagged template literals to define scripts, this could look like:

const myTask = task({
  name: 'my task',
  input: '*.lowercase',
  output: '*.uppercase'
}, ({ input }) => bash`
  input="${input}"
  output="${input.replace(/\.lowercase$/, '.uppercase')}"

  cat $input | awk '{print toupper($0)}' > $output
`)

These could be written to the folder the task is being ran, which has the added benefit of being able to simply cd data/<id> to run the script.

This will involve

  • having the tag function return something we can pick up on, so that during the lifecycle hook which creates the operation, it can inject the dir of the task (similar to how if the operationCreator returns a string, it considers it a { shell: true } child process)
  • nice way to remove spaces from beginning of lines (regex)
  • probably return the spawned child process (as opposed to promise)
  • a "base" to add support for other languages (assuming they have unique quirks, file extension, etc)
@thejmazz
Copy link
Member Author

thejmazz commented Oct 8, 2017

Userland implementation from 9a2e750 for quick reference:

const script = ({ dir, program }) => (strings, ...values) => {
  let content = ''
  strings.forEach((str, i) => {
    content += str + (values[i] || '')
  })

  const scriptLocation = path.resolve(dir, 'script.' + (() => {
    switch (program) {
      case 'bash': return 'sh'
      case 'python': return 'py'
    }
  })())

  fs.writeFileSync(scriptLocation, `
#!/usr/bin/env ${program}
${content.replace(/\n\ {2}/g, '\n')}
  `.trim())

  fs.chmodSync(scriptLocation, '755')

  const cp = spawn(scriptLocation)

  cp.on('error', (err) => console.log(`${scriptLocation} error:`, err))
  cp.on('close', () => console.log(`${scriptLocation} closed`))
  cp.on('exit', () => console.log(`${scriptLocation} exited`))
  cp.on('disconnect', () => console.log(`${scriptLocation} disconnected`))

  cp.stdout.on('data', (chunk) => console.log(`${scriptLocation} stdout: ${chunk}`))
  cp.stderr.on('data', (chunk) => console.log(`${scriptLocation} stderr: ${chunk}`))

  return cp
}

const myTask = task({
  name: 'my task',
  input: '*.lowercase',
  output: '*.uppercase'
}, ({ input, dir }) => script({ dir, program: 'bash' })`
  input="${input}"
  output="${input.replace(/\.lowercase$/, '.uppercase')}"

  cat $input | awk '{print toupper($0)}' > $output
`)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant