crystal-lang / crystal

The Crystal Programming Language
https://crystal-lang.org
Apache License 2.0
19.33k stars 1.61k forks source link

Problem in design of with `docs` in crystal compiler #12971

Open AssertionBit opened 1 year ago

AssertionBit commented 1 year ago

Discussion

Well I am not so much active user of Crystal Language but using it sometimes for my own things. But there is small misunderstanding in core design of CLI.

Crystal compiler doesn't know the target which I would like to build, but, it knows from where to start building the docs? Shards building targets by the start file and then starts work fine and clear! But why shards then don't know how to build docs? It is some times very strange to understand, that tool, that has clear understanding of which target I want to build and create something useful for it can not do anything about that.

I would like to see moving of docs functionality crystal compiler -> shards. I know that shards is dependency manager, but maybe then add some remarks or more clean functionality with targets where package manger with targets section.

Other way is more clean documentation about who is who. I don't understand what is core design of compiler and dm (dependency manager). Compiler as it is, compiler-as-toolchaing or something else?

straight-shoota commented 1 year ago

Crystal compiler doesn't know the target which I would like to build, but, it knows from where to start building the docs?

Yes, that's a significant difference. Doc generation only takes types and methods into account, and does not care about top-level code. But that's relevant for building an actual program because top-level code serves as an entry-point to the program.

But why shards then don't know how to build docs?

Why would it need to? It's a dependency resolver, not a compiler. The shards build functionality is a bit of an extra out of its primary scope but it's due to the target definition in shard.yml.

Moving docs to shards is basically impossible. It needs access to the AST which we won't do in Crystal. I suppose it could be an option to have shards docs just call crystal docs. But that doesn't really improve anything. It just dilutes the boundary between compiler and dependency manager.

Other way is more clean documentation about who is who. I don't understand what is core design of compiler and dm (dependency manager). Compiler as it is, compiler-as-toolchaing or something else?

I don't understand what information you're missing. crystal is a compiler. shards is a dependency manager. Both are used for their respective tasks with Crystal projects.

asterite commented 1 year ago

Why would it need to? It's a dependency resolver, not a compiler.

What about shards build? I think that command should exist in crystal, not shards. That might be part of the confusion, which is totally reasonable.

straight-shoota commented 1 year ago

shards build deals with the targets property in shard.yml. That file is a responsibility of shards. If the compiler were to handle that, it would have to be able to read shard.yml, which just adds complexity to the compiler (needs libyaml) and functionality that is also outside its core competency as well.

j8r commented 1 year ago

It can be possible, as shards build call crystal build, to have shards docs calling crystal docs. It is the case with cargo doc and rustdoc, the latter being also in the compiler. It could be useful to be library-aware when generating API docs.

AssertionBit commented 1 year ago

I was confused about automated documentation builds. I clearly understand difference between shards and crystal. But for me there is a problem in reserving targets. Shards does this automatically: installs, compiles and runs my project and requires from me to select target if multiple; crystal always requires from me to select targets even if one. But meybe need target-specific documentation builds?

I understand that this is sounds weird. Like for what did I need in such feature? But from my perspective: what if I want to build documentation for specific target? Not the entire project?

Maybe need to make the crystal docs to require specific target? Or allow to build docs for target that not the file-based project? And as @j8r said:

It can be possible, as shards build call crystal build, to have shards docs calling crystal docs. It is the case with cargo doc and rustdoc, the latter being also in the compiler. It could be useful to be library-aware when generating API docs.

This is very useful feature for versioning documentation like DLang has with version or debug thing.

Like including additional information to generated docs with remark: "Version Foo incudes this functionality".

straight-shoota commented 1 year ago

You can do that with crystal docs as well if you pass the path to a file that is to be used as entry-point: crystal docs src/docs_version1.cr

But I don't think this is necessarily something that shards needs to support.

AssertionBit commented 1 year ago

But does it not breaking interface? Isn't it better to have unified interface that works by one rules in any direction?

asterite commented 1 year ago

Why is the targets thing needed in shard? What's it's relationship with solving and installing dependencies?

asterite commented 1 year ago

For a bit of historical context:

  1. Originally the dependency resolver was in Crystal itself, called crystal deps
  2. We didn't have time to focus on that dependency manager and a new one was built by someone else (ysbaddaden) in the meantime, and it was much better: shards
  3. We then made crystal deps call shards internally. The problem with that is that errors reported by that command mentioned shards so it was a bit confusing.
  4. Eventually we removed crystal deps and had users use shards directly.

The "problem" is that, somehow, shards got bigger, with commands like shards build that have nothing to do with dependency resolution.

So in my opinion:

  1. We should remove shards build from shards, together with the targets attribute in shards.yml
  2. Introduce a new file to specify build targets. This could be YAML or something else. My preference would be YAML, even if it requires installing YAML (but YAML is ubiquitous)
  3. Introduce crystal build which would build the default target, and crystal build target ... to build a specific target.

Of course... I'm not sure all of that is really worth it.

I think it's just easier to know that you can build projects with crystal build or shards build as a convenience, and generate docs with crystal docs. It's not perfect, but it works.

AssertionBit commented 1 year ago

After some time and thoughts on this idea, I totally agree. If You could separate targets put of the crystals and shards view it could be cooler.

In case of creating the targets, we could create files like shard.project-name.yaml for mono repo needs and left the default shards.yaml as default target