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

Run mako templates as standalone executables #358

Closed
wants to merge 3 commits into from

Conversation

TheJJ
Copy link

@TheJJ TheJJ commented Mar 20, 2022

That way, mako can directly evaluate template files and can be used as a file interpreter.

When using either

  • #!/usr/bin/env -S python3 -m mako -s -a --
  • #!/usr/bin/env -S mako-render -s -a -- as shebang, a file can be templated directly, and behaves similar to a PHP script.
    With this commit, Python can be run as PyHP :)

This is possible because -s or --strip-shebang strips away the shebang line in the input template.
Program arguments get modified so you can even run ./awesome.mako --my-argument test --rolf

-a shifts the template argv - the sys.argv is replaced by the cmdline args to the template execution.
It can then use regular argparse for parsing further arguments.

One can use this new feature to dynamically generate static config files, for example.
Or generate arbitary files when using something like execfs.

So this could be a simple example for an executable test.mako file:

#!/usr/bin/mako-render -s --
This is awesome!
<%
# hehe like pyhp :)
import argparse
cli = argparse.ArgumentParser()
cli.add_argument("stuff")
# argparsing also works as expected for an executable:
args = cli.parse_args()
%>
stuff: ${args.stuff}

run as

$ ./test.mako yay
This is awesome!

stuff: yay

@zzzeek
Copy link
Member

zzzeek commented Mar 20, 2022

this would need the console_scripts entrypoint to really be complete right?

@TheJJ
Copy link
Author

TheJJ commented Mar 21, 2022

Hi!
I think the installation of /usr/bin/mako-render using console_scripts is already implemented here:

mako/setup.cfg

Lines 69 to 70 in c814024

console_scripts=
mako-render = mako.cmd:cmdline

@zzzeek
Copy link
Member

zzzeek commented Mar 23, 2022

OK, looked at this for another two minutes.

mako-render still seems like a weird name for something that's using the .mako file as an executable. maybe it's better as mako-invoke, and it strips the shebang in all cases then. a little less awkard maybe.

also. this is...a php thing? why are we doing this? php is sort of both a scripting language and a templating language, and it's also not really linked to anything else that acts like a container language for it, so I can see why that might exist.

but mako, it's just templating, and it's well embeddable into Python. if you want python scripting, .py already does all this. if you want a .py script with embedded mako templates, that not hard either.

i dunno just seems weird to have ".mako" as chmod 775 :)

@bourke
Copy link
Member

bourke commented Mar 23, 2022

I could see myself using this functionality for certain tasks, but I don't think it belongs in core Mako — it feels more like one of the utilities I'd use alongside, where maintainability is less of a concern. For one thing, stripping shebangs asks for a lot of testing, and some of that would need to be Windows-specific (which is certainly possible, but unpleasant). I also find the concept of ".mako" files as chmod 775 to be surprising, and I imagine other users would too.

Interesting approach, though!

@TheJJ
Copy link
Author

TheJJ commented Mar 25, 2022

If you prefer creating something like /usr/bin/mako-exec, I can create it :)
As mako-render is like 95% of what I need, i thought it would be better to add it there.

This feature can be used to easily create, for example, configuration files for tools that can invoke binaries as input, or in combination with a fuse-filesystem (something like execfs) which executes files when reading them, one can finally auto-generate config files that have no scripting features otherwise (e.g. xorg-config, sway-config, ...).

So I'd love to see some support upstream in mako, because maintaining a shebang-compatible mako launcher works too, but seems kinda redundant when mako-render is nearly there 😄

@TheJJ
Copy link
Author

TheJJ commented Apr 9, 2022

What do you think now? What do I have to change in order to get this or some variant shippable? :)

@bourke
Copy link
Member

bourke commented Apr 9, 2022

I'm -1 on this, I'm afraid.

This is absolutely something Mako can be used for (and as you've demonstrated, good for), but in my view it's not what Mako is designed for. "Support upstream" for an outlier use case (no matter how interesting) is more than I'd want to take on.

If you build a shebang-compatible Mako launcher, I'd use it; I just don't want to maintain it 😄

@zzzeek may feel otherwise, though... paging @zzzeek !

@TheJJ
Copy link
Author

TheJJ commented Apr 10, 2022

If it's a better way, I can also update the mako-parser with an option to ignore shebangs, then the whole input pipeline can stay the same but the parser will filter out the shebang line.

Copy link
Member

@zzzeek zzzeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we might as well accept it once the implementation can be simplified.

mako/__main__.py Outdated Show resolved Hide resolved
mako/cmd.py Show resolved Hide resolved
@TheJJ TheJJ force-pushed the mainfunction branch 2 times, most recently from 00603db to 64a31f2 Compare April 16, 2022 23:51
@TheJJ
Copy link
Author

TheJJ commented Apr 16, 2022

I've now added test cases for shebang stripping and argument passing 😸

@TheJJ TheJJ force-pushed the mainfunction branch 3 times, most recently from ae6f756 to f2f328a Compare April 17, 2022 00:45
@TheJJ
Copy link
Author

TheJJ commented May 7, 2022

Pling plong :) Is there anything I should improve further?

Copy link
Member

@zzzeek zzzeek left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm still generally uncomfortable with this patch as I still dont see a good use case for mako templates as shell scripts

mako/cmd.py Show resolved Hide resolved
mako/cmd.py Outdated Show resolved Hide resolved
@TheJJ TheJJ force-pushed the mainfunction branch 2 times, most recently from 23af5dd to 092d7a2 Compare May 26, 2022 15:18
That way, mako can directly evaluate template files,
or can be used as a file interpreter.

When using `#!/usr/bin/env -S mako-render -s --` or
`#!/usr/bin/env -S python3 -m mako -s --` as file shebang,
a file can be templated directly, and behaves similar to a PHP script.
With this commit, Python can basically be run as PyHP :)

This is very useful for example for generating static config files,
especially in combination with some `execfs` which executes files
when they are read. That way one can even programatically customize
the a precious `xorg.conf`.
@TheJJ
Copy link
Author

TheJJ commented May 29, 2022

I've now added the cli option for shifting commandline args, and I'm passing the remaining cli arguments as template variable template_argv.

# we do this so templates can handle further args on their own
if options.shift_args:
saved_sys_argv = sys.argv
sys.argv = [options.input] + options.args
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hey there -

what I want is:

  1. do not change sys.argv at all
  2. make a new template variable "sys_argv" with [options.input] + options.args, or whatever is most appropriate for argparse
  3. users that want to use argparse in a template use parser.parse_args(sys_argv)

that's it!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

okay great, I'll implement that :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll mark it resolved when the next patch is put up (with the issue resolved :) )

@zzzeek
Copy link
Member

zzzeek commented Sep 16, 2023

We dont really do much with Mako these days and I think this use case can be accomplished outside of Mako without changing mako itself, so closing.

@zzzeek zzzeek closed this Sep 16, 2023
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

Successfully merging this pull request may close these issues.

None yet

3 participants