-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Discussion: Crystal Install - Install Crystal Command Line Tools #3328
Conversation
There is a discussion about using Shards as a build system, and another one about installing binaries. I don't know of any CLI tool in Crystal at the time of writing. Since Crystal is compiled, it's more complicated to have CLI tools loading code at runtime. Also, there is no kemal-cli nor any binary in minitest. I.e. we need actual use cases. |
Allright, I found one usecase: ICR. It could be nice to be able to install/upgrade it with a single command. Thought I believe it would be better baked into Shards. |
I have quite a strong opinion on the proliferation of language-specific package managers that have sprung up in the past few years. Having to have a distro-specific package manager plus I think we should leave package management of command line tools written in crystal to the system package manager. Then, as a user, I don't have to care about which language my tools are written in, and I don't have to know what package manager they were installed with, or attempt to keep my system up to date using 12 different package managers. I just have to use one. Unfortunately it's a bit late for that vision to be true, but I don't think crystal should contribute to this mess. People who write tools in crystal should provide install instructions for their tool, or attempt to get the tool into various package repositories. Ideally, crystal tools would be installed by downloading the source from github and using Such an approach does make it a little harder for the tool developer, but I think that with appropriate tooling (standardized makefiles, or a little binary that's included in VCS which bootstraps the crystal toolchain e.g. Unfortunately, this approach isn't so practical when you're developing tools for other people in the crystal community. They already have crystal and shards installed, and just want a simple command to run to install the tool they need to develop their crystal project (think In summary, I propose:
Opinions welcome. |
I think this can be another program out of Crystal. |
@david50407 shards can run post install scripts. I think that library management, and tool management is in scope for shards. Anything that's outside the scope of a single project such as installing binaries outside the project isn't though. |
Another usecase micrate, so I can run migrations in my project. But I don't know how would that work, does it get installed relative to the current project, or globally? And how is it added to the PATH? |
@asterite My vision is that with micrate, you could use |
I agree with @RX14. The use cases I imagine is template expansion. Create a class / specs together. I would expect that the shard's post install might symlink a wrapper to a crystal script that will do the work. If used as a script it might be simpler to for example customize which .ecr template to use. For small tools developers use I feel comfortable with this approach. If the tool is a framework with some utilities, it will need some part of the shard on runtime. So the binary delivery won't make it here. Maybe some guidance can appear for doing such post install symlinks and we can work from there. |
@RX14 I agree with the tools being project specific, the use case is definitely supporting rails-esk clis and for things like micrate. I like the tools section in the shard file... although I think if packages supply their own tools then they should be referenced as the name in the shardfile. The following example assumes that an application has a shard that has a cli tool. This example also assumes each shard can only have 1 cli package. Application name: my-app
version: 0.1.0
dependencies:
micrate:
github: juanedi/micrate
branch: master
development_dependencies:
icr:
github: greyblake/crystal-icr
branch: master Child Shard name: micrate
version: 0.1.0
tool: micrate.cr
license: MIT Command The second argument would link to the name referenced in applications shard.yml. |
@RX14 @asterite @ysbaddaden Anything else to add here? |
Yes, I don't think a I don't think the whole "clone a repository / download a tarball; pull dependencies; build executables; install into $PATH" is really need. As @RX14 stated, OS packages are a better solution, especially since the compiler isn't required to run the executables. That being said, Cargo has this feature, so maybe we'll eventually want it. Maybe when Crystal has lots of global and very useful developer tools that don't have to be dependencies (like One may build such a tool, though. |
@RX14 stated his dislike of language specific package managers, but are they not successful? They ask the developer to only know about their developer eco-system. What is the point of cross compiling if you still have to do the leg work for |
Closing in favor of crystal-lang/shards#95 and crystal-lang/shards#110. @ysbaddaden looking for any development assistance there? |
@jwaldrip Just because an idea is successful doesn't mean it's the right thing to do. Developer tools should have a clean crystal-specific package manager because they can stay self-contained to a project. More general system tools and daemons often have very different, more complex requirements than developer tools in terms of dependency management. They may want to be installed system-wide, they may want to run scripts on the host system, they may have system libraries they depend on, they may want to install init scripts. Such requirements are well out of scope for shards, and end up creating more work for the user and developer, as they both go for the "obvious solution" of using shards and later along find it limiting. By limiting the scope of shards now we avoid creating problems later. We should instead focus on the problem of installing system tools and daemons as separate and orthogonal to shards' mission. I covered some of my ideas for addressing this problem above. The end goal would be to make installing crystal daemons and tools that aren't in your package manager as easy as installing C tools: acquire source, Using simple tools like make, and not providing an official package manager also aids getting into official package repositories. Getting packages into distro's official package repositories is a huge boon because the packages just work. They have init scripts, they install binaries in the right place, the default config is edited if required for the distro, and you have a more mature package manager in general, with people handling security updates and distro-specific issues. In effect: installing developer tools needs to be easy, installing system tools and daemons needs to be correct. |
100% Agree. My focus was ONLY on developer tools. |
@jwaldrip maybe I got a little confused by this comment. Were you not refuting my point? |
@RX14 I was refuting in the context of dev packages. |
For the anecdote, Shards was initially called Harbor, and it was a compiled Bower client. A single binary file, without any requirements. Why? Because I was fed up of having to install Node to install NPM to install Bower to install JS/CSS dependencies in pure Ruby projects that didn't use Node, at all. |
What about sysadmin or productivity tools that are non project specific where
Examples (via cargo install):
While few tools exist in crystal there are some and more coming. |
I wanted to start this discussion before I continued down the wrong path....
tl;dr
Crystal needs an easy way to install command line packages from local and remote sources.
Why?
Command line tools are at the heart of the developer ecosystem and are one of the reasons why many languages become popular. Let's have Crystal take a lesson from it's ruby cousin and allow for a native way to install global command line packages in the path with
crystal install
.How?
Crystal would use a similar method as shards for fetching remote dependencies and would use the shard.yml to actually build and install the binary. The follow commands should work:
crystal install git:https://github.com/ysbaddaden/minitest.cr.git
crystal install github:ysbaddaden/minitest.cr
crystal install /some/local/path
The follow commands would:
shards install
within the directory, therefore fetching all the dependencies.crystal build --release -o $PATH
and install each of the shards binaries into the local directory.Changes to crystal shards:
In order for this to work, I would suggest adding a bin section to the shard file that would correlate with the bin name and the crystal file that contains the code for said binary.
What's next?
I would like this to drive a discussion with the Crystal core team and the crystal community before I move forward.