gravity
gravity copied to clipboard
Does Gravity have a package manager or module system?
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 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 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...
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.
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.
That's quite cool, actually. @marcobambini is this something that could work for Gravity?
I would love to see something like Go has. It is really simple and elegant sulution.
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...
I'd like to have one for Gravity... looking for a simple and elegant solution as suggested by @Dohxis.
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:
-
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
-
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 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.
@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?
It is in gravity.c in src/cli/ delegate function load_file.
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!
Thanks for the explanation @Dohxis, I really like the gravity get [package]
way.
Do you know how get is implemented? I guess with curl.
I think gravity pull
or gravity attract
would be a much better syntax – and call the record of packages satellites.txt
, of course. ⚛️ 🛰
Record of packages is a must - too many times have I pip install
ed something and it failed because of subdependencies.
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]"
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.
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.
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?
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?
Also I definitely would prefer 1.x.x
over npm style ^1.0.0
.
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
.
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.
for example, if a branch is named
1.x.x.
Maybe for branches, you'd start with @, and for commit hashes, you'd do #?
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.
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...
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.
@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)
Sorry, I confused bytecode with binary.
Sorry, I confused bytecode with binary.
No worries! Anyway, an arch section could be used for native modules
What would be the command to install all the packages form satellites.json
?
Just gravity pull
(no args, like npm install
) ?
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
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).