gravity icon indicating copy to clipboard operation
gravity copied to clipboard

Does Gravity have a package manager or module system?

Open bates64 opened this issue 7 years ago • 34 comments

I've always wanted to create one and Gravity looks like an amazing language - would a creation such as npm/yarn be up for grabs?

bates64 avatar Mar 07 '17 22:03 bates64

I hope @marcobambini takes inspiration from Go's packages rather than Node's package atrocity. With Go there's no need for a "package manager," which is really nice.

badcc avatar Mar 07 '17 22:03 badcc

@badcc mind explaining for a person not familiar with Go? I meant more npm the website (acting as a central repository etc) and yarn the interface - I've found being able to just "install" xyz into a project and know other people can install all of my project dependencies quite comforting...

bates64 avatar Mar 07 '17 22:03 bates64

Haskell has a very nice package system that's tied to Github as it's central repository. From the sounds of it it's similar Go; any git repository can act as a package.

bates64 avatar Mar 07 '17 22:03 bates64

Go encourages packages to be hosted on Bitbucket, GitHub, Google Project Hosting and Launchpad. To use a package in your project, you just include the URL in your import statement (and run go get URL to fetch it). They created https://godoc.org/ which stores auto-generated API docs of packages. If it doesn't yet exist and you search the url, it'll add it automatically.

badcc avatar Mar 07 '17 22:03 badcc

That's quite cool, actually. @marcobambini is this something that could work for Gravity?

bates64 avatar Mar 07 '17 22:03 bates64

I would love to see something like Go has. It is really simple and elegant sulution.

Dohxis avatar Mar 08 '17 06:03 Dohxis

I've always wanted to create one and Gravity looks like an amazing language - would a creation such as npm/yarn be up for grabs?

I've always wanted it too. I would be glad to help...

parro-it avatar Mar 09 '17 10:03 parro-it

I'd like to have one for Gravity... looking for a simple and elegant solution as suggested by @Dohxis.

marcobambini avatar Mar 09 '17 10:03 marcobambini

I have far more experience with node than with Go, but if I understood, Go uses any git repo as source for dependencies.

This is good because we avoid the "single registry" problems that affects npm.

The feature I really like of npm are:

  1. semver ranges for dependencies in package manifest. For example, if I specify a dependencies of "express": "ˆ2.3.0", npm will automatically install 2.4.x, 2.5.x ecc. when they will be available

  2. multiple versions of same package npm will allow you to depend on a package A 1.0 and on package B. If package B depends on package A 2.0, they (package B and your root package) both can load the version of package A they expect.

AFAIK, gravity import file modules relative to CWD. This could be problematic to implement 2) @marcobambini do you think it could be easy/desiderable to import file modules relative to the importing file?

parro-it avatar Mar 09 '17 11:03 parro-it

@parro-it import can be implement with any policy, it is delegate responsibility to locate the module/file to import. I added support for importing relative to CWD as a simple example of a delegate not as a real solution.

marcobambini avatar Mar 09 '17 11:03 marcobambini

@parro-it import can be implement with any policy, it is delegate responsibility to locate the module/file to import. I added support for importing relative to CWD as a simple example of a delegate not as a real solution.

Nice! Could you point to the file where you implement such example policy?

parro-it avatar Mar 09 '17 11:03 parro-it

It is in gravity.c in src/cli/ delegate function load_file.

marcobambini avatar Mar 09 '17 11:03 marcobambini

In my opinion, @marcobambini with the help of community should choose the path and with everyones help we sooner or later will have a working package manager. I would suggest to have a simple solution just like Go has:

  • No central repository
  • Encourages to use a version control system (GitHub, BitBucket..)
  • No need to have any actual package manager, just a simple command gravity get [package]

For those who do not know how Go works here is an example. Lets say you want to use package YY from http://github.com/XX/YY you simply run a simple command go get github.com/XX/YY and import it to your project import "github.com/XX/YY" Done!

Simple and innovative!

Dohxis avatar Mar 09 '17 15:03 Dohxis

Thanks for the explanation @Dohxis, I really like the gravity get [package] way. Do you know how get is implemented? I guess with curl.

marcobambini avatar Mar 09 '17 16:03 marcobambini

I think gravity pull or gravity attract would be a much better syntax – and call the record of packages satellites.txt, of course. ⚛️ 🛰

towerofnix avatar Mar 09 '17 16:03 towerofnix

Record of packages is a must - too many times have I pip installed something and it failed because of subdependencies.

bates64 avatar Mar 09 '17 17:03 bates64

image

Please, this - something as follows would be ❤️ :

$ gravity pull github.com/nanalan/[email protected]
installed github.com/nanalan/[email protected]: # latest version it can find that fits "1.0.x"
- github.com/gravity-lang/[email protected] # dependencies automagically resolved

$ cat satellites.json # `gravity pull` adds all dependencies to this file so you can install all dependencies at once
[
  "github.com/nanalan/meteorite": [ "1.0.x" ]
]

$ ls .satellites
[email protected]
[email protected]

$ cat main.gravity # or whatever
import Meteorite from "github.com/nanalan/[email protected]"

bates64 avatar Mar 09 '17 18:03 bates64

Better import functionality is also really important I guess. Something like

import {function, Class} from "package";

and

import Package from "package";

Besides names gravity pull [package] and satellites.json are awesome! JSON because we already have support for it.

Dohxis avatar Mar 09 '17 18:03 Dohxis

Also, dropping the github.com/ prefix unless something else is given (for whatever reason) would probably be a good move. suggested by @firedrake969

Assume it's github unless otherwise stated? username/repo and github.com/username/repo should be the same as far as the name resolver is concerned.

bates64 avatar Mar 09 '17 18:03 bates64

I'm not sure if this has been implied yet, but I definitely agree with @nanalan's suggestion (the example w/satellites.json), specifically the versioning.

Go's default package installer (go get) doesn't let you install specific versions - instead, it just installs the latest from the URL. That can create problems if multiple packages depend on different versions of a certain package, but the proposal (username/repo@version) would eliminate that issue while keeping the installation process pretty simple.

This is more complex, but Python allows you to install packages from repositories based on commits and branches - @commit_hash or @branch, respectively. Could that be considered?

matthewr6 avatar Mar 09 '17 18:03 matthewr6

This is more complex, but Python allows you to install packages from repositories based on commits and branches - @commit_hash or @branch, respectively. Could that be considered?

This would be really nice. especially since not all Git hosts have a /releases.

Maybe each library repo should have a file (versions.json or similar) showing where to get certain versions?

ghost avatar Mar 09 '17 18:03 ghost

Also I definitely would prefer 1.x.x over npm style ^1.0.0.

bates64 avatar Mar 09 '17 18:03 bates64

especially since not all Git hosts have a /releases.

Wouldn't Git hosts have tags still, though?

In any case, one potential problem with using commit hashes, branches, and tags/releases would be defining what's what - for example, if a branch is named 1.x.x.

matthewr6 avatar Mar 09 '17 18:03 matthewr6

I like the idea of pushing a commit to release called v1.0.0 or whatever for updates. Or commiting changes to a file VERSION with the current version number and it working out what to based on when that changed... all git hosts have commits, right?

Tags, though.

bates64 avatar Mar 09 '17 18:03 bates64

for example, if a branch is named 1.x.x.

Maybe for branches, you'd start with @, and for commit hashes, you'd do #?

ghost avatar Mar 09 '17 18:03 ghost

Just realised something - ~/.gravity/satellites can probably contain every package that has ever been installed if each is versioned, and symlinks can be used for caching and stuff. That'd be nice.

bates64 avatar Mar 09 '17 18:03 bates64

I completely agree with @nanalan suggestions.

The idea of caching all downloaded packages under ~/.gravity/satellites is awesome, it could really make the difference in terms of performance...

Another doubt that come to me is if it's better to publish a package in bytecode or source code form

Bytecode should be better for closed-source packages. I bet it also could be more performant. But it could be difficult to publish/manage compiled file to a git repo.

Also, I'm not sure if gravity could manage to import compiled files... @marcobambini?

I think depending on a particular branch or commit could be a useful feature but not indispensable, and could be implemented in a future iteration...

parro-it avatar Mar 09 '17 19:03 parro-it

A Lockfile functionality similar to Yarn's lockfile, which ensure consistency between packages of different versions and their dependencies upon installing, updating and removing dependencies. Could be opt-in with a command like gravity lock.

I also agree with @Dohxis about the import functionality. The current import can lead to conflicts between class-, function- and variable names. On top of that I'd propose export functionality like ECMAScript so you can choose what API to expose within your module.


@parro-it I believe published packages could be of both. The engines/archs could be specified in satellite.json:

{
  "arch": {
    "darwin": ["x86_64"], // this is automatically implied
    "archlinux": ["i386"],
    "debian": ["i386", "amd64"]
  }
}

Using git tags to version releases the compiled module. Perhaps with pre-defined format of file names: <module name>.<os>-<arch>.<ext>, for example my-module.darwin-x86_64.dylib, my-module.archlinux-i386.so and my-module.debian-amd64.so which are within *.tar.gz and *.tar files of same name.

fnky avatar Mar 11 '17 21:03 fnky

@parro-it I believe published packages could be of both. The engines/archs could be specified in satellite.json:

By "binary", I meant the json form that contains the multiplatform bytecode that gravity produce. An architecture field could, anyway, be used for native modules, if gravity will support them (I hoep it will)

parro-it avatar Mar 12 '17 12:03 parro-it

Sorry, I confused bytecode with binary.

fnky avatar Mar 12 '17 18:03 fnky

Sorry, I confused bytecode with binary.

No worries! Anyway, an arch section could be used for native modules

parro-it avatar Mar 12 '17 19:03 parro-it

What would be the command to install all the packages form satellites.json ? Just gravity pull (no args, like npm install) ?

YurySolovyov avatar Apr 08 '17 20:04 YurySolovyov

Also, dropping the github.com/ prefix unless something else is given (for whatever reason) would probably be a good move.

That would be all kinds of wrong. The package manager should be 100% platform-neutral. @heyitsmeuralex

neysofu avatar Oct 16 '17 20:10 neysofu

As a user, I would want to at least have a central gravity package search engine to find useful packages that I'd like to use in my project.

Perhaps it could simply be a website that you could register your package on that links to the git repository on the web?

Also, I'd recommend implementing environment variables that allow you to tell the gravity package manager (erm, what's it called? blackhole?) where it's cache is. That way users can put the cache wherever they like (e.g. I'd want mine somewhere in ~/.cache/, for example).

sbrl avatar Dec 31 '17 22:12 sbrl