shards icon indicating copy to clipboard operation
shards copied to clipboard

[RFC] Bundler like require.

Open didactic-drunk opened this issue 5 years ago • 12 comments

Provide a feature similar to bundler groups.

# Requires all shards listed in shard.yaml.
Shards.require

# Requires a group.
Shards.require :development

One possible way to implement this feature:

  1. Have shards generate one .cr per group.
  2. Shards.require requires the generated file(s).

Other bundler features may or may not be included.

didactic-drunk avatar May 03 '20 03:05 didactic-drunk

What's the usecase?

straight-shoota avatar May 03 '20 09:05 straight-shoota

Less work in each application maintaining require statements?

My primary purpose in grouping is multiple apps within 1 repo.

For example I have a web service, command line app and queue consumer. ~50% of the gems and library are shared. Almost all of the application code is shared. The web framework and many supporting shards are unique to the web service. TTY/console and a few misc shards are unique to the command line app. The queue service uses neither. Database, queue, and s3 etc are common between them.

didactic-drunk avatar May 03 '20 15:05 didactic-drunk

This is impossible to do because require is a compile-time thing while here it seems you need to parse the shard.yml at runtime to know this.

Well, it's possible using macro run, but I don't encourage that. You can always write a shard to do that

asterite avatar May 03 '20 15:05 asterite

Oh, well, if a cr is generated then it can be done using macros... but in general I don't know if requiring all shards at once is good. Specially, some shards might depend on others and the require order you need io use must be very specific, and using the same order in shard.yml might be tricky or not obviously related.

asterite avatar May 03 '20 15:05 asterite

@asterite If shard a depends on b, doesn't a normally require "b" solving most ordering problems?

didactic-drunk avatar May 03 '20 15:05 didactic-drunk

@didactic-drunk Is this only about compile-time requires in Crystal code? In my experience the main use case for bundler groups is to group dependencies and be able to selectively install them as necessary using bundle install --with group and bundle install --without group. So that would affect how shards installs dependencies.

straight-shoota avatar May 03 '20 17:05 straight-shoota

Another use case it comes to my mind is when an shard provides an extension or an implementation of some kind. For example, database connectors for crystal-db. Currently we must explicitly require the specific connector.

waj avatar May 03 '20 19:05 waj

Actually generating the files within a "pseudoshard" would be really simple. Shards knows the dependency graph so the statements could be generated in the right order. And then just use require "_shards/group" to load that file. No need of macros or anything fancy.

Of course this first needs some way of defining shard groups within shard.yml.

waj avatar May 08 '20 05:05 waj

My initial use case was for applications not libraries.

Your solution works except for for partial inclusion:

  1. Application a uses shard foo and requires "_shards/group".
  2. Shard foo uses part of shard bar by requiring bar/baz.
  3. Shard foo doesn't want to include all of bar.

Possible fixes are opting in or out from graph inclusion with a flag or two. Preferably having a flag for all shards or per dependency. Or specifying what to require.

dependencies:
  foo:
    github: foo/foo
    require: bar/baz
  bar:
    github: bar/bar
    require: false

didactic-drunk avatar May 09 '20 05:05 didactic-drunk

Allowing to specify require key would solve the issue of requiring different but equally-named shards in the same time 👍

Sija avatar May 12 '20 00:05 Sija

@Sija , why? As long as the shard key indicates where to install in the CRYSTAL_PATH (.crystal/shards / lib) the scenario you mention will still not be handled.

bcardiff avatar May 12 '20 12:05 bcardiff

@bcardiff Oh, right. I forgot that shards are not scoped within the lib directory.

Sija avatar May 12 '20 14:05 Sija