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

Make output relative to tape file #121

Open
spenserblack opened this issue Oct 31, 2022 · 6 comments
Open

Make output relative to tape file #121

spenserblack opened this issue Oct 31, 2022 · 6 comments

Comments

@spenserblack
Copy link

spenserblack commented Oct 31, 2022

# in directory called demo
mkdir -p subdir
cat <<EOF > tape.tape
Output ./subdir/tape.gif
Type "Hello, World!"
Enter
Sleep 5s
EOF
cd ..
vhs ./demo/tape.tape

Currently this usage would write to demo/../subdir/tape.gif instead of demo/subdir/tape.gif, because it seems that the output is currently relative to the current directory, not the tape's directory.

I thought this would be useful because I noticed the output of vhs new demo.tape doesn't work "out of the box", because the examples/ directory must exist. If the output could be relative to the tape file, then examples/demo.tape could use ./demo.gif, and the file would also work "out of the box" as the embedded output of vhs new. Making outputs relative to the tape would make results easier to reproducible.

@muesli
Copy link
Member

muesli commented Oct 31, 2022

I understand where you're coming from, but I wonder if that isn't less intuitive behavior 🤔

@spenserblack
Copy link
Author

spenserblack commented Oct 31, 2022

A new keyword definitely shouldn't be added without careful consideration, but what do you think about OutputRelative or something similar?

While it's definitely far more common for paths to be relative to the directory that the process is executed in, not the current file, many tools will have some way to get the file's directory (dirname $0 in Bash, __dir__ in Ruby, etc.). Not arguing for that added complexity, but I'm just saying that there's almost always some way to build paths relative to the currently interpreted file.

I should note that my initial issue is actually that vhs new tape.tape doesn't work immediately unless I either create an examples/ directory or change the path in the new tape. I think it's a bit awkward that vhs new tape.tape might not be enough to be a runnable file, and an additional step might be required. This proposal is inspired by that, as I was thinking of a way to allow examples/demo.tape to continue to work as both an example in this repo and as the source for the new command, and allow the newly created tape to always work without additional steps.

@spenserblack
Copy link
Author

I'll note that, while checking out behavior, my initial assumption was that output.gif would be relative to the current directory, and ./output.gif would be relative to the file's directory. Not sure how common that assumption is, though.

@rm-dr
Copy link
Contributor

rm-dr commented Nov 27, 2022

It isn't possible to get a relative output file if vhs gets input through stdin (like vhs < path.tape), since vhs doesn't "see" that path at all. Tapes with relative outputs must be loaded as an argument, like vhs path.tape.

Here are a few thoughts:

  • Relative paths will be very helpful if we add an Include keyword, or another feature that pulls extra files. Those are input files, though, not output files.
  • Relative output paths would be pretty counterintuitive. Maybe a cli argument, like --output-relative? A .tape keyword wouldn't really make sense, because we can't get relative output if we load the file through stdin.

As for vhs new, we'd better fix the fact that the file it creates doesn't work. We could do this by putting relative paths in all the demo files, and cding into the examples directories before giving them to vhs.

@spenserblack
Copy link
Author

spenserblack commented Nov 27, 2022

  • Maybe a cli argument, like --output-relative?

An --out-dir or similar argument could be useful (taking some inspiration from TypeScript).

$ cat file.tape
Output "out.gif"
...

$ vhs --out-dir /path/to/context file.tape
$ ls /path/to/context
out.gif ...

This by itself wouldn't resolve the new tape not working out-of-the-box, but maybe that should be a separate issue. But maybe all of the examples could use --out-dir examples instead of all referencing examples/name.format.

@spenserblack
Copy link
Author

spenserblack commented Nov 27, 2022

because we can't get relative output if we load the file through stdin.

By the way, interpreted languages like Ruby and JavaScript (Node) allow one to reference paths relative to the current file:

require_relative '../path/to/file'
require('../path/to/file')

Both of these languages support interpretation from stdin AFAIK.
Right now I think that --out-dir is a better solution (I'm happy to change the issue title 🙂), but it might be worth looking into what these languages/interpreters do when the code referencing relative paths comes from stdin.

Edit: Just to give further context to how other tools resolve relative paths, Node will interpret paths relative to the current file, but use the working directory if interpreting from stdin. For example

$ echo "console.log('hello, world');" > greet.js
$ echo "require('../greet.js');" > subdir/index.js
$ node subdir/index.js
hello, world
$ node < subdir/index.js
(stacktrace)
$ cd subdir
$ node index.js
hello, world
$ node < index.js
hello, world

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

3 participants