Feature flags for shards (like features in Rust crates)

I need ability to pass some parameters to shard during postinstall (during shards install) and build (during shards build). I want to discuss the solution, that I may implement if I have a free time in the future.

When I implemented Embeddable / Interoperable with ruby - #44 by I3oris GitHub - ahrushetskyi/polycrystal: Integrate Crystal into ruby , I need to install shard (Anyolite) but not run postinstall script, or run it with some parameters. And to pass the flag to build it for ruby.

My idea is as follows:

  1. Add features and/or configs to shard.yml:
dependencies:
  dependency:
    github: user/repo
    features: 
      - key1
      - key2
      - key3
    configs:
      keyA: valueA
      keyB: valueB

Features may be passed as env variable to postinstall scripts as one ENV variable:
SHARD_FEATURES=key1,key2,key3
And may be passed to build step as compiler flags:
-D feature_shardname_key1 -D feature_shardname_key2 -D feature_shardname_key3
shardname should be taken from shards shard.yml`

I’m not sure yet how to pass configs, but the most logical solution is also to pass them as env variables to both postinstall and build:

SHARDNAME_CONFIG_keyA=valueA
SHARDNAME_CONFIG_keyB=valueB
# and, maybe, to pass everything as json to allow free-form configs:
SHARDNAME_CONFIGS={"keyA":"valueA","keyB":"valueB"}

Shard’s shard.yml may contain default values for features and/or configs. It may also contain list of all existing feature keys.

Also, usefull option is to configure flags per target for shards build

At some point we envision the idea of having some sort of configuration for crystal programs at build time. That concept I think it belongs more to a “project file” rather than “the dependency file”. And we currently don’t have a “project file”, we kind of overlap the two concepts in shards.

Leaving that aside for a moment, Crystal does not build each dependency. So it does not seem accurate to put configs in the dependency declaration.

I’m not sure what the post_install you want to configure does. But from the outside I would say that maybe the solution is not using post_install to build something. It might be enough to use it to scaffold some scripts or base code for your project that could be configurable by some mean.

I’m happy to follow a bit more of the details of a “project file” vs “the dependency file”, but maybe we can focus on the use case you have right now and how to find a solution with the current tools.

2 Likes

Anyolite integrates ruby or mruby into Crystal.
It’s postinstall script compiles ruby interpreter and some shims and makes it linkable to Crystal.

There is no way right now to select ruby or mruby, and in my case I need to add third option - no ruby.
Right now, environment variable should be passed to shards install, and then compiler flag should be manually passed to build.

Not using postinstall will force other users of the shard to build ruby manually, and there is still no way to configure what bindings, ruby or mruby should be used

1 Like

I see that the post install ends up calling a rake to generate some glue files. My point is that there is that the post install could, at most, leave some script like ./script/glue in the project root that will do that, on demand, for the host project. There is room even for some additional options or interactivity. You might even be able to do that outside anyolite to start poking with that idea if needed since the whole shard is checked out at ./lib/anyolite.

If the defaults are fine, then the user will need to run manually some command on the post install.
Another benefit is that on a project that depends on anyolite you will be able to choose whether to checking those files or generated them always.

There is already the option to select a specific configuration file for Anyolite (see Using Ruby instead of mruby · Anyolite/anyolite Wiki · GitHub).
This requires only setting an environment variable and then running shards as usual (if you encounter any bugs, just open an issue).

I also added a special empty configuration file if you want to link the components by yourself.

However, I do like the idea of being able to set specific configuration options (or have more flexibility when using shards). Environent variables are a way to circumvent this, but it’s not the most elegant way.

EDIT: Also shards still seems to have the problem on Windows of only being able to run executable files - which makes the postinstall routine unnecessarily complicated. I get the argument that shards is not a build system, but it would be really helpful if one would be able to install shards with a single step instead of “Set environment variables” → “Use shards” → “Build shard”.

1 Like