-
-
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
Package manager #1357
Comments
As discussed with @asterite Shards shall supersede the current crystal deps command. Development on the package manager will continue there for the time being. We'll eventually figure out if it shall be merged into the Crystal source code or be kept separated (as long as it's tightly integrated/embedded with Crystal's distributions). The main feature still missing is the lock file (crystal-lang/shards#12) then to integrate it as crystal deps. |
Looking forwards to this very much 👍 👍 🚀 🚀 💃 Comments/questions:
also thanks @ysbaddaden for the work so far! 👍 |
|
probably you won't need many of the features that YAML provides, and I guess you have to think about security when loading YAML because it can deserialize complex types, where as toml is more simple and just supports arrays, hash, string, & number types. |
Is there a defined serialization of TOML, given abstract input data? Last time I checked I couldn't find it, but I think it's important to have in order to support tooling that automatically edits the file to bump the version number, add/remove dependencies etc. Stdlib YAML doesn't have serialization either yet, but it should be comparatively easy to add. |
In TOML you have to put quotes around every string, so having to put quotes in YAML from time to time is not an issue. There's also the thing that TOML isn't stable. We have a parser for it, it's just not in the standard library because it's not standard enough. We can also compare a shard.yml with a Cargo.toml file. To me, YAML looks much cleaner without all those quotes. Also, those There's also the thing that @jhass mentions, there's many ways to represent a TOML and I can't figure a way to do a |
@jhass what do you mean by "Stdlib YAML doesn't have serialization either yet" ? When I say serialization I mean turning a Crystal string into yaml, and then back again(deserialize). YAML can just do much more than only a string, and sometimes it's a security issue (like being able to create Ruby symbols from YAML). |
I mean that the serialization API is not available yet, but the standard does define a canonical serialization and the backend libyaml does have an API for it. With TOML, if there's a canonical serialization, we also have to write the complete serializing code. But I couldn't even find a definition for such. |
Ugh...please not TOML. It's the worst markup language. Ever. The issue with YAML is that, if you want auto-tooling, you're going to store a heck of a lot in the tree structure (the indentation the user used, the whitespace surrounding the colon, etc.), as well as use some sort of ordered hash to avoid literally wrecking the order of the file, if you want the tooling to not change the whole file around every time one "bumps the version number". What about a ridiculously simple INI-ish thing, like:
|
I would like to offer a modified approach that would provide a few additional benefits. My main concern is with the _releases branch. I do not think it is a good solution to the problem b/c the mechanism of a branch doesn't really correspond to the need. Another issue is the usability of the project.yml file. Either the user will have to follow a very strict schema or the parser will have to have plenty of heuristics to make the format flexible. The former isn't very user friendly, and the later would generally require use of the same parser library whenever the file needs to be read to ensure proper info. But other tools might want to use that info too, perhaps some not even written in Crystal. To overcome these issues, I'd like to propose an idea I came up with some time ago that I use for my Ruby projects. I have a humanized form of metadata, in an easily edited YAML file, though it can be a Ruby script or other format, like TOML, or combination of files actually, it doesn't really matter. Than there is a canonical metadata file. A tool takes the editable file(s) and generates the canonical file. The canonical format follows a strict schema with no exceptions. This makes it readable by other programs without any heuristic processing. To solve the _releases issue, this tool can also look back at past tagged versions and pull the relevant dependency info into the canonical file. This approach gives maximum flexibility to the developer while still providing a single strict metadata file for use by the package manager and other tools. |
The _releases branch hasn't been implemented. This is open for discussion, and as I understand it, it would mostly allow to speed things up, yet hide the gory details behind a few tools —that would work as you described. For now the different shard.yml come from version tags. The format of the YAML file will indeed be specified and I'm thinking about a validate command (Travis does that for instance). |
I don't understand what you mean, could you elaborate? @asterite I have a question:
Where are these dependencies 'installed', in |
The The |
If I may throw in my 5ct:
Otherwise it looks solid and I could certainly work with it, so I'm happily waiting for it. 👍 |
If we go for something else than |
Thank you @ysbaddaden. I vote for enforcing semver but only because it just ensures to keep all the stuff that handles version numbers simple (or simpler). About format, I vote yaml because it's 'prettier' to read, and I guess crystal users in general also like nice looking (i.e. readable) syntax, because that's one of the selling points of this language. But I'm really not too opposed to the other options either. About third party directory name, I don't really see an issue with the community just establishing @asterite About discoverability... In addition to automatically listing github/bitbucket repos with crystal code (I assume you mean automatically), could we also have it that random people can submit their project to this list (as a 'hardcoded' project)? Obviously, this would only be for those who do not host on github/bitbucket. And the submission should have their git repo url somewhere, so that the presense of a Oh and also, what about gitlab.com? (if they consider crystal as a language) |
Question: The releases branch sounds like a pain to handle. Why not just rely on git tags, and ensure each released version has the correct dependencies specified with each tag? |
@jwaldrip The releases branch will be managed by a tool, so it won't be a pain. And you need to have fast access to all dependencies of every version released. It's not enough to have access to the dependencies of a particular tag, you need them all to resolve conflicts. |
Hi there, just started to explore crystal recently and wanted to lend a couple of thoughts:
|
*Of course, there will be a list as said in point 1 (probably something like https://crystalshards.herokuapp.com/), but that's obviously not a reliable source of metadata information because crystal projects don't have to be on this list. |
I am very very strongly against
Not to mention GitHub API which turns (1) into a JSON download and (2) into an archive download (URL provided in JSON). |
(@asterite I'm just guessing here though, I may be wrong?) But why are you very strongly against a |
People provided multiple reasons to not like the _releases branch. I don't have much to add. Do dependencies really need to be checked beforehand? I mean, if you're gonna be downloading the whole library anyway, why bother with having a way to get just the release-info files? If you're concerned about speed. The vast majority of dependencies will be on GitHub. If it's specialcased like I mentioned then this is not a concern anymore. The size of the _releases branch can also get big, by the way. |
No nested dependencies ala The lock file is being implemented. It's a flattened list of all dependencies and only applies to the project. See crystal-lang/shards#27 |
Just reading myself: sorry for the tone. I didn't mean to be rude! |
Semantic versioning: we could enforce that. But does this mean just the "1.x.x" syntax? Elm seems to check changes in the code, although I'm not sure how would you do that. DSL: The problem with using a DSL is that you'll have to fire the compiler multiple times to compile that. And then it becomes hard to communicate data between these processes. In Ruby it's easier because you can Command line: I also think doing Child dependencies: as @ysbaddaden mentions, in node.js you do |
semantic versioning: I meant the code checks, no idea how they do it - I just wanted to put it in as an idea as I found that to be amazing about elm. Not sure how it plays out in practice. I'm perfectly fine with putting it on a "future wishlist" or abandoning it as too complex :) |
_Semantic Versioning:_ yes as the format for semver, nothing more. _DSL:_ I don't know why the compiler would have to run multiple times. I would see that the only thing that uses the shardfile and its lock would be the shards/deps command itself. Once the dependencies are downloaded they are in the directory tree and can be required using "..." or their name as defined in the CRYSTAL_PATH. When cloning a project, it just customary to run a dependencies command. _Child Dependencies:_ I see your point, but my counter point is that in bundler it gets annoying when two libraries child dependencies conflict. This could certainly be the exception, but I don't think it lends to as much flexibility... unless there is a way to both. |
On semver standard is described here: http://semver.org/ Format is pretty Best Regards, 2015-09-06 18:32 GMT+02:00 Jason Waldrip notifications@github.com:
|
@waterlink I agree with that too. |
There would only be one definitive file, but the developer can work with whatever source format they'd like. The distinction between them is similar to the difference between Gemfile and Gemfile.lock. |
👍 for the shard ideas presented by @jwaldrip |
On the topic of source formats. What the specific format is does not matter much, developers will learn it and most of the formats mentioned are human friendly enough to be useable. I'm partial to json, but if it's yaml, toml, or something else, it's not going to bother me. |
Ok...this is kind of off-topic...but I can't help it... Guess what the full name of Kirby 64 was?
(notice the bolded text) Sorry, but it seemed kind of funny to me. :) |
I vote next tool be named Kirby. |
Starting from b86a5b8 The idea is that eventually |
+1 for "Kirby", haha. @jwaldrip - as already mentioned the hierarchical dependencies á la npm/iojs does not work with Crystal. This is the reason I strongly believe semver should be enforced. The semantics of the scheme makes it straight forward to deduce which latest possible versions are compatible for all dependants - or if there's a conflict in version needs that needs to be worked out! "Flat namespace" == great need for a good convention of dependency compatibility checks == semver. The "strictness" of the semver rules aren't a problem at all - they're super straight forward. |
This is the last time I express myself about semver: it's nice, follow it if you can and want, but I won't enforce it.
That being said. Semver is very good. It helped focus to keep a sane version scheme and a stable code that can can somehow rely on. You should try to apply its principles as much as possible. But you can't follow it blindly, you can't enforce it, and I won't. This is developer responsibility. |
Fair enough, the point that developers efforts of versioning correctly might not match reality is a good one. I still don't see how a good unification of dependencies can be achieved without that "promise" of a strife to get it as right as humanly possible though. In any event, this will be my last commenting on SemVer too. Having "official" modules managing in crystal is great! |
Despite not being a big SemVer fan, you need to define a standard versioning systems if you want dependencies to be managed correctly. If someone adds package B version Maybe not as strict as SemVer, but some kind of control. |
So what is the status on the package manager? |
The current status is that Maybe we should close this issue now in favour of more specific ones? |
Yes, let's close this and add issues in shards as they appear :-) |
Since one of the goals was to make it part of the core, is there any plan to merge shards into crystal?
Jason Waldrip On Oct 14, 2015, 8:17 AM -0600, Ary Borenszweignotifications@github.com, wrote:
|
Yes, once everything stabilizes we'll look into that again. |
I've scan through the shards project, finding there's no plan for support command like |
Hi @glyh! Here's an issue with some discussion on that topic crystal-lang/shards#81 Come join our forum, it may be more suited for discussion on questions like this :) |
@caspiano Thanks. I don't think that's the place though. The author is reluctant to implement this feature. BTW, this language's competitors have great support for package managing. I'm talking about Nim and Go. V doesn't seem to have a good one though. |
This is the main issue tracking this feature from the Roadmap.
Crystal will provide a built-in package manager. We really want this to be the only package manager so it's easier to build a collaborative community.
We want a truly decentralized package manager. These ideas could make it work:
_releases
) with metadata for dependencies for each version. These are cummulative, so version 0.2 contains metadata for 0.1 and 0.2.Projecfile
, use YAML, both forproject.yml
and for the metadata fileproject.yml
require "..."
, so for example "webmock.cr" will be installed in "lib/webmock", and that directory will contain the direct checkout of the project (so it has thesrc
directory in it)require
logic changes to that if you dorequire "foo"
, we check if there'sfoo.cr
in CRYSTAL_PATH, orfoo/foo.cr
, orfoo/src/foo.cr
(this last one is the one that will be used for dependencies installed via the package manager). With this logic, the current CRYSTAL_PATH value doesn't need to changeWith the above, when you do
crystal deps install
, all first-level dependencies are gathered. From there we go to each depednency's repository and check out the special_releases
branch to get all metadata for all versions of that first-level dependency. We apply this recursively until we get all the metadata for all involved libraries. The previous process should be fast, because only that metadata branch must be checked out, and only once for each library (and we can parallelize the requests). Then we can solve conflicts and install what's needed.For discoverability, we can list github/bitbucket repositories that have crystal code and that also have that special
_releases
branch, which in turn contains all the information for every version of the library.For all of this, the easiest thing would be to build on top of @ysbaddaden's shards, which already has the desired YAML format, probably has some logic for semver, etc.
The text was updated successfully, but these errors were encountered: