[Propose] Create shard.yml use app as target when run crystal init app some_name

When run crystal init app foo, current, it will generate a shard.yml like this:

name: foo
version: 0.1.0

targets:
  foo:
    main: src/foo.cr

This is inconvenient when write Dockerfile because the build target is mutable.

I propose change the default to always app when init a app, like this:

name: foo
version: 0.1.0

targets:
  app:
    main: src/foo.cr

This will make things simpler.

In fact, The lucky change shards like this when create a new lucky project use lucky_cli.

Thanks.

2 Likes

I don’t understand what you mean? How is it mutable? It’s just the name that you chose for your project in crystal init and usually won’t change (unless you explicitly do that).

The target name is used by shards build and it’s also the name of the resulting binary. I don’t think it makes much sense to generically name binaries app. That would be confusing if you have multiple Crystal projects, which app is it?
Of course there can be use cases where you want some specific other name for the binary then the name of the project. That’s fine, you can easily change it. Just go with what you like. But that’s not good as default behaviour.

2 Likes

I consider it not necessary use different target name for different app project, probably current selection more suitable for a CLI application, e.g. crystal init cli cli_name, it need a different name(cli_name in above case) for search it from $PATH, but for application, app is enough. for the mutable, what i means is, if target is app, we can use conventional app all the places instead of different name for different project, in config files just like Dockerfile etc …

Changing to a default name does not sound great to me. Lets not return to the bad old days of a.out, please. If it is irritating enough perhaps there could be a command line switch to shards init to allow specifying the name of the executable, but I have some problems seeing this as an issue that needs solving.

crystal init app foo => use app as default target
crystal init cli | lib foo => use cli as default target

The shards run command allows you to not specify the target name if there is only one target defined.

That seems to check the boxes for the developer experience after a crystal init app, right?

crystal init just creates a skeleton of a project that is (iirc) meant to be a good common denominator for initializing a project. But you really could do the same thing with a shell script that cats out a shard.yml, some initial .cr files, and whatever else you want. Then just use that script instead of crystal init. That’s what I do because I got tired of deleting 70% of what it generates each time.

2 Likes

agreed.

In fact, that exact what i do for now, i add a command like cr instead of crystal, taht do some replace hack when the first sub-command is init like cr init ???.

In fact, except replace the initialize target name into app, i replace the content of src/foo/version.cr into this:

module Foo
  VERSION = {{ `shards version "#{__DIR__}"`.chomp.stringify }}
end

Instead of the old hard code VERSION = 0.1.0, we don’t need all places fill with version.

if people like do things like this, i consider maybe we have some place to improve.