{"action":"created","issue":{"url":"https://api.github.com/repos/manastech/crystal/issues/1357","labels_url":"https://api.github.com/repos/manastech/crystal/issues/1357/labels{/name}","comments_url":"https://api.github.com/repos/manastech/crystal/issues/1357/comments","events_url":"https://api.github.com/repos/manastech/crystal/issues/1357/events","html_url":"https://github.com/manastech/crystal/issues/1357","id":104709675,"number":1357,"title":"Package manager","user":{"login":"asterite","id":209371,"avatar_url":"https://avatars.githubusercontent.com/u/209371?v=3","gravatar_id":"","url":"https://api.github.com/users/asterite","html_url":"https://github.com/asterite","followers_url":"https://api.github.com/users/asterite/followers","following_url":"https://api.github.com/users/asterite/following{/other_user}","gists_url":"https://api.github.com/users/asterite/gists{/gist_id}","starred_url":"https://api.github.com/users/asterite/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/asterite/subscriptions","organizations_url":"https://api.github.com/users/asterite/orgs","repos_url":"https://api.github.com/users/asterite/repos","events_url":"https://api.github.com/users/asterite/events{/privacy}","received_events_url":"https://api.github.com/users/asterite/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/manastech/crystal/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/manastech/crystal/labels/package%20manager","name":"package manager","color":"fad8c7"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":29,"created_at":"2015-09-03T14:37:10Z","updated_at":"2015-09-05T15:43:52Z","closed_at":null,"body":"This is the main issue tracking this feature from the [Roadmap](https://github.com/manastech/crystal/wiki/Roadmap#package-manager).\r\n\r\nCrystal 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.\r\n\r\nWe want a truly decentralized package manager. These ideas could make it work:\r\n\r\n- No global directory where all deps are installed: it's local to each project (lib/libs directory)\r\n- Each repo has a special branch (maybe `_releases`) with metadata for dependencies for each version. These are cummulative, so version 0.2 contains metadata for 0.1 and 0.2.\r\n- Crystal provides a command to release a new version, pushing to that special branch, and creating a tag\r\n- Use [Semantic Versioning](http://semver.org/) \r\n- Automatically download recursive dependencies\r\n- Resolve conflicts\r\n- Remove `Projecfile`, use YAML, both for `project.yml` and for the metadata file\r\n- Include name and version in `project.yml`\r\n- The name above is used for the directory in which it is installed, and used by `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 the `src` directory in it)\r\n- The `require` logic changes to that if you do `require \"foo\"`, we check if there's `foo.cr` in CRYSTAL_PATH, or `foo/foo.cr`, or `foo/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 change\r\n- Probably [rename \"libs\" to \"lib\"](https://github.com/manastech/crystal/issues/321)\r\n\r\nWith 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.\r\n\r\nFor 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.\r\n\r\nFor all of this, the easiest thing would be to build on top of @ysbaddaden's [shards](https://github.com/ysbaddaden/shards), which already has the desired YAML format, probably has some logic for semver, etc."},"comment":{"url":"https://api.github.com/repos/manastech/crystal/issues/comments/137968495","html_url":"https://github.com/manastech/crystal/issues/1357#issuecomment-137968495","issue_url":"https://api.github.com/repos/manastech/crystal/issues/1357","id":137968495,"user":{"login":"trans","id":23423,"avatar_url":"https://avatars.githubusercontent.com/u/23423?v=3","gravatar_id":"","url":"https://api.github.com/users/trans","html_url":"https://github.com/trans","followers_url":"https://api.github.com/users/trans/followers","following_url":"https://api.github.com/users/trans/following{/other_user}","gists_url":"https://api.github.com/users/trans/gists{/gist_id}","starred_url":"https://api.github.com/users/trans/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/trans/subscriptions","organizations_url":"https://api.github.com/users/trans/orgs","repos_url":"https://api.github.com/users/trans/repos","events_url":"https://api.github.com/users/trans/events{/privacy}","received_events_url":"https://api.github.com/users/trans/received_events","type":"User","site_admin":false},"created_at":"2015-09-05T15:43:52Z","updated_at":"2015-09-05T15:43:52Z","body":"Let me try to clarify what I was saying b/c I am not sure it was understood.\r\n\r\n1. A _releases branch is not required b/c a tool to stuff the information into that branch can just as easily stuff the information into a file on the current branch. The package manager only needs to checkout the latest tag (or master or specified branch if working with a development branch) and the file will contain all the dependency information for the current tag/branch and all the versions that came before it as well. (Although not quite this simple) One can think of it as a registry that is updated with each new release never loosing any of the previous information for prior releases.\r\n\r\n2. My other suggestion of separating user edited metadata from the canonical file would allow developers to use whatever format they preferred (e.g. YAML, JSON, TOML, etc.) as long as an adapter existed in the aforementioned tool to convert it to the canonical format. It might feel a little odd to allow this degree of flexibility, but I think it is better than alienating potential developers.\r\n\r\nNote that the canonical dependency information and the project metadata could be kept in separate files or just one file, since the data is generated.\r\n"}}