Skip to content

Revamping wrapper scripts in CURI #455

Closed
@patrickbkr

Description

@patrickbkr

(I know I break the rules by presenting a solution in the first post. But I mostly seek feedback on my proposal, I don't want to kick of a brainstorming round.)

The bat wrappers we generate on Windows don't kick it and never will. To give one example: It's currently impossible to run zef install 'ABC:ver<0.6.13>:auth<zef:colomon>' on Windows. The < and > characters don't survive a trip through CMD-land.

Thus I believe I need to pick up rakudo/rakudo#3716 (comment) again. Here is an updated copy of that post.

The following is my (potentially incorrect) understanding of how things work. Please correct me where I'm wrong.

A CURI (CompUnit::Repository::Installation) is a store represented as a folder for installed modules. It contains everything a module needs, including the actual something.raku script. All contents (including that script) are stored in a way opaque to the user. Running such an installed script requires calling the following Raku method:

CompUnit::RepositoryRegistry.run-script('some_script');

Wrappers which basically only execute the above call are installed in the curi_store/bin subfolder. For those wrapper scripts to work their path must be in PATH or they need to be called with their absolute path. (Sidenote: On Windows there are no shebang lines. There additional .bat files are generated.)

There are three standard CURIs every Rakudo installation brings with it: core, site and vendor installed into $prefix/share/perl6/. In principle the site and vendor CURIs could be shared between multiple Rakudo installations, but that doesn't make much sense, as every installation brings its own set with it.
There can be additional CURIs in arbitrary places. Which CURIs are used is configurable.

Relocatable Rakudo installations have a well defined directory layout. Things (rakudo executables, CURIs, libs, ...) are always in the same place relative to each other.

There are different situations we need to consider:

  • Standard CURIs, part of a non-relocatable installation: Typical case when Rakudo is installed by the distro. The CURIs belong to a specific Rakudo installation. -> Directly use the full path of the rakudo excutable in the shebang line.
  • Standard CURIs, part of a relocatable installation: Different approaches are possible:
    • Use env in the shebang line and hope that the PATH points to the Rakudo this CURI belongs to. (That's not guaranteed.)
    • Use absolute paths and provide a tool to update the shebang lines. One then needs to call that script whenever the installation is moved around. (That's what Strawberry Perl does.)
    • Let the wrapper be a shell script or native executable and dynamically determine the rakudo path based on the location of the wrapper. Something like $wrapper_path/../../../bin/rakudo.
  • Custom CURIs: Such CURIs don't belong to a specific rakudo installation, so it's difficult to classify them as relocatable or non-relocatable. The only options I see are:
    • Rely on env and just use the Rakudo that happens to be in the PATH.
    • Provide a tool to set / change the shebang lines. Then it's up to the user to configure the wrappers to his liking.

In every case we want to keep our ability to call a script by passing it to some rakudo: /some/rakudo /path/to/curi/share/perl6/site/bin/my_script.raku.

I tend towards the following:

  • We always have two files per script in bin/. A *.raku file that is not executable and an executable sh/exe wrapper script/program.
  • When building a non-relocatable Rakudo we default to using absolute paths in the standard CURI wrappers.
  • When building a relocatable Rakudo, we default to using relative paths in the standard CURI wrappers.
  • CURIs somehow remember (in some configuration file) how its wrapper scripts should look. The CURI implementation in Rakudo will respect this configuration and generate wrappers accordingly. The goal here is to never mix different wrappers in a specific CURI.
  • Non-standard CURIs default to using the Rakudo found in PATH.

Before I start implementing things, I'd like to get the outline right.
There are two key points that I feel I want to have a second opinion on (because they are unconventional).

  1. Native executables

I want to generate native executables for each script in a CURI on Windows. I believe I can do that by integrating https://sr.ht/~patrickb/Devel-ExecRunnerGenerator/ into the Rakudo core. It's basically a native executable that can be tuned by attaching a config to the end of the binary file to do what we want it to do. My idea is to compile that executable as a part of the Rakudo build process. The executable is 16.5KiB.
Potential problems I see: Dynamically creating executables on Windows might be an anti-virus / Microsoft security nightmare. I do not know if this will be a problem or if it can be worked around.

  1. Two files per script

I want to always put two files in the bin/ folder. A *.raku script, not marked executable, and a sh script (*nix) / .exe (Windows). That's the only way I managed to come up with that gives us the flexibility we need to support all of our use cases.
Potential problems I see: People hate having twice as many files in bin/ or having non-executable files in bin/ or having non-raku files in bin/.

Metadata

Metadata

Assignees

No one assigned

    Labels

    rakudoBig changes to Rakudo

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions