Code Monkey home page Code Monkey logo

gx's Introduction

gx logo

gx

The language-agnostic, universal package manager

gx is a packaging tool built around the distributed, content addressed filesystem IPFS. It aims to be flexible, powerful and simple.

gx is Alpha Quality. While not perfect, gx is reliable enough to manage dependencies in go-ipfs and is ready for use by developers of all skill levels.

Table of Contents

Background

gx was originally designed to handle dependencies in Go projects in a distributed fashion, and pulls ideas from other beloved package managers (like npm).

gx was designed with the following major goals in mind:

  1. Be language/ecosystem agnostic by providing git-like hooks for adding new ecosystems.
  2. Provide completely reproducible packages through content addressing.
  3. Use a flexible, distributed storage backend.

Requirements

Users are encouraged to have a running IPFS daemon of at least version 0.4.2 on their machines. If not present, gx will use the public gateway. If you wish to publish a package, a local running daemon is a hard requirement. If your IPFS repo is in a non-standard location, remember to set $IPFS_PATH. Alternatively, you can explicitly set $IPFS_API to $IPFS_API_IPADDR:$PORT.

Installation

$ (cd ~ && GO111MODULE=on go get github.com/whyrusleeping/gx)

This will download, build, and install a binary to $GOPATH/bin. To modify gx, just change the source in that directory, and run go build.

Usage

Creating and publishing new generic package:

$ gx init
$ gx publish

This will output a 'package-hash' unique to the content of the package at the time of publishing. If someone downloads the package and republishes it, the exact same hash will be produced.

package.json

It should be noted that gx is meant to work with existing package.json files. If you are adding a package to gx that already has a package.json file in its root, gx will try and work with it. Any shared fields will have the same types, and any fields unique to gx will kept separate.

E.g. A single package.json file could be used to serve both gx and another packaging tool, such as npm. Since gx is Alpha Quality there may be some exceptions to the above statements, if you notice one, please file an issue.

Installing a gx package

If you've cloned down a gx package, simply run gx install or gx i to install it (and its dependencies).

Dependencies

To add a dependency of another package to your package, simply import it by its hash:

$ gx import QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr

This downloads the package specified by the hash into the vendor directory in your workspace. It also adds an entry referencing the package to the local package.json.

Gx has a few nice tools to view and analyze dependencies. First off, the simple:

$ gx deps
go-log              QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52 1.2.0
go-libp2p-peer      QmWXjJo15p4pzT7cayEwZi2sWgJqLnGDof6ZGMh9xBgU1p 2.0.4
go-libp2p-peerstore QmYkwVGkwoPbMVQEbf6LonZg4SsCxGP3H7PBEtdNCNRyxD 1.2.5
go-testutil         QmYpVUnnedgGrp6cX2pBii5HRQgcSr778FiKVe7o7nF5Z3 1.0.2
go-ipfs-util        QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0

This just lists out the immediate dependencies of this package. To see dependencies of dependencies, use the -r option: (and optionally the -s option to sort them)

$ gx deps -r -s
go-base58           QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
go-crypto           Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
go-datastore        QmbzuUusHqaLLoNTDEVLcSF6vZDHZDLPC7p4bztRvvkXxU 1.0.0
go-ipfs-util        QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
go-keyspace         QmUusaX99BZoELh7dmPgirqRQ1FAmMnmnBn3oiqDFGBUSc 1.0.0
go-libp2p-crypto    QmVoi5es8D5fNHZDqoW6DgDAEPEV5hQp8GBz161vZXiwpQ 1.0.4
go-libp2p-peer      QmWXjJo15p4pzT7cayEwZi2sWgJqLnGDof6ZGMh9xBgU1p 2.0.4
go-libp2p-peerstore QmYkwVGkwoPbMVQEbf6LonZg4SsCxGP3H7PBEtdNCNRyxD 1.2.5
go-log              QmSpJByNKFX1sCsHBEp3R73FL4NF6FnQTEGyNAXHm2GS52 1.2.0
go-logging          QmQvJiADDe7JR4m968MwXobTCCzUqQkP87aRHe29MEBGHV 0.0.0
go-multiaddr        QmYzDkkgAEmrcNzFCiYo6L1dTX4EAG1gZkbtdbd9trL4vd 0.0.0
go-multiaddr-net    QmY83KqqnQ286ZWbV2x7ixpeemH3cBpk8R54egS619WYff 1.3.0
go-multihash        QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
go-net              QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
go-testutil         QmYpVUnnedgGrp6cX2pBii5HRQgcSr778FiKVe7o7nF5Z3 1.0.2
go-text             Qmaau1d1WjnQdTYfRYfFVsCS97cgD8ATyrKuNoEfexL7JZ 0.0.0
go.uuid             QmcyaFHbyiZfoX5GTpcqqCPYmbjYNAhRDekXSJPFHdYNSV 1.0.0
gogo-protobuf       QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV 0.0.0
goprocess           QmSF8fPo3jgVBAy8fpdjjYqgG87dkJgUprRBHRd2tmfgpP 1.0.0
mafmt               QmeLQ13LftT9XhNn22piZc3GP56fGqhijuL5Y8KdUaRn1g 1.1.1

That's pretty useful, I now know the full set of packages my package depends on. But what's difficult now is being able to tell what is imported where. To address that, gx has a --tree option:

$ gx deps --tree
├─ go-base58          QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
├─ go-multihash       QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
│  ├─ go-base58       QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
│  └─ go-crypto       Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
├─ go-ipfs-util       QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
│  ├─ go-base58       QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
│  └─ go-multihash    QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
│     ├─ go-base58    QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
│     └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
├─ go-log             QmNQynaz7qfriSUJkiEZUrm2Wen1u3Kj9goZzWtrPyu7XR 1.1.2
│  ├─ randbo          QmYvsG72GsfLgUeSojXArjnU6L4Wmwk7wuAxtNLuyXcc1T 0.0.0
│  ├─ go-net          QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
│  │  ├─ go-text      Qmaau1d1WjnQdTYfRYfFVsCS97cgD8ATyrKuNoEfexL7JZ 0.0.0
│  │  └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
│  └─ go-logging      QmQvJiADDe7JR4m968MwXobTCCzUqQkP87aRHe29MEBGHV 0.0.0
└─ go-libp2p-crypto   QmUEUu1CM8bxBJxc3ZLojAi8evhTr4byQogWstABet79oY 1.0.2
   ├─ gogo-protobuf   QmZ4Qi3GaRbjcx28Sme5eMH7RQjGkt8wHxt2a65oLaeFEV 0.0.0
   ├─ go-log          Qmazh5oNUVsDZTs2g59rq8aYQqwpss8tcUWQzor5sCCEuH 0.0.0
   │  ├─ go.uuid      QmPC2dW6jyNzzBKYuHLBhxzfWaUSkyC9qaGMz7ciytRSFM 0.0.0
   │  ├─ go-logging   QmQvJiADDe7JR4m968MwXobTCCzUqQkP87aRHe29MEBGHV 0.0.0
   │  ├─ go-net       QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
   │  │  ├─ go-text   Qmaau1d1WjnQdTYfRYfFVsCS97cgD8ATyrKuNoEfexL7JZ 0.0.0
   │  │  └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   │  └─ randbo       QmYvsG72GsfLgUeSojXArjnU6L4Wmwk7wuAxtNLuyXcc1T 0.0.0
   ├─ go-ipfs-util    QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
   │  ├─ go-base58    QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   │  └─ go-multihash QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
   │     ├─ go-base58 QmT8rehPR3F6bmwL6zjUN8XpiDBFFpMP2myPdC6ApsWfJf 0.0.0
   │     └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   └─ go-msgio        QmRQhVisS8dmPbjBUthVkenn81pBxrx1GxE281csJhm2vL 0.0.0
      └─ go-randbuf   QmYNGtJHgaGZkpzq8yG6Wxqm6EQTKqgpBfnyyGBKbZeDUi 0.0.0

Now you can see the entire tree of dependencies for this project. Although, for larger projects, this will get messy. If you're just interested in the dependency tree of a single package, you can use the --highlight option to filter the trees printing:

$ gx deps --tree --highlight=go-crypto
├─ go-multihash       QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
│  └─ go-crypto       Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
├─ go-ipfs-util       QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
│  └─ go-multihash    QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
│     └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
├─ go-log             QmNQynaz7qfriSUJkiEZUrm2Wen1u3Kj9goZzWtrPyu7XR 1.1.2
│  └─ go-net          QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
│     └─ go-crypto    Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
└─ go-libp2p-crypto   QmUEUu1CM8bxBJxc3ZLojAi8evhTr4byQogWstABet79oY 1.0.2
   ├─ go-log          Qmazh5oNUVsDZTs2g59rq8aYQqwpss8tcUWQzor5sCCEuH 0.0.0
   │  └─ go-net       QmZy2y8t9zQH2a1b8q2ZSLKp17ATuJoCNxxyMFG5qFExpt 0.0.0
   │     └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0
   └─ go-ipfs-util    QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1 1.0.0
      └─ go-multihash QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku 0.0.0
         └─ go-crypto Qme1boxspcQWR8FBzMxeppqug2fYgYc15diNWmqgDVnvn2 0.0.0

This tree is a subset of the previous one, filtered to only show leaves that end in the selected package.

The gx deps command also has two other smaller subcommands, dupes and stats. gx deps dupes will print out packages that are imported multiple times with the same name, but different hashes. This is useful to see if different versions of the same package have been imported in different places in the dependency tree. Allowing the user to more easily address the discrepancy. gx deps stats will output the total number of packages imported (total and unique) as well as the average depth of imports in the tree. This gives you a rough idea of the complexity of your package.

The gx dependency graph manifesto

I firmly believe that packages are better when:

1. The depth of the dependency tree is minimized.

This means restructuring your code in such a way that flattens (and perhaps widens as a consequence) the tree. For example, in Go, this often times means making an interface its own package, and implementations into their own separate packages. The benefits here are that flatter trees are far easier to update. For every package deep a dependency is, you have to update, test, commit, review and merge another package. That's a lot of work, and also a lot of extra room for problems to sneak in.

2. The width of the tree is minimized, but not at the cost of increasing depth.

This should be fairly common sense, but striving to import packages only where they are actually needed helps to improve code quality. Imagine having a helper function in one package, simply because it's convenient to have it there, that depends on a bunch of other imports from elsewhere in the tree. Sure it's nice, and doesn't actually increase the 'total' number of packages you depend on. But now you've created an extra batch of work for you to do any time any of these are updated, and you also now force anyone who wants to import the package with your helper function to also import all those other dependencies.

Adhering to the above two rules should (I'm very open to discussion on this) improve overall code quality, and make your codebase far easier to navigate and work on.

Updating

Updating packages in gx is simple:

$ gx update mypkg QmbH7fpAV1FgMp6J7GZXUV6rj6Lck5tDix9JJGBSjFPgUd

This looks into your package.json for a dependency named mypkg and replaces its hash reference with the one given.

Alternatively, you can just specify the hash you want to update to:

$ gx update QmbH7fpAV1FgMp6J7GZXUV6rj6Lck5tDix9JJGBSjFPgUd

Doing it this way will pull down the package, check its name, and then update that dependency.

Note that by default, this will not touch your code at all, so any references to that hash you have in your code will need to be updated. If you have a language tool (e.g. gx-go) installed, and it has a post-update hook, references to the given package should be updated correctly. If not, you may have to run sed over the package to update everything. The bright side of that is that you are very unlikely to have those hashes sitting around for any other reason so a global find-replace should be just fine.

Publishing and Releasing

Gx by default will not let you publish a package twice if you haven't updated its version. To get around this, you can pass the -f flag. Though this is not recommended, it's still perfectly possible to do.

To update the version easily, use the gx version subcommand. You can either set the version manually:

$ gx version 5.11.4

Or just do a 'version bump':

$ gx version patch
updated version to: 5.11.5
$ gx version minor
updated version to: 5.12.0
$ gx version major
updated version to: 6.0.0

Most of the time, your process will look something like:

$ gx version minor
updated version to: 6.1.0
$ gx publish
package whys-awesome-package published with hash: QmaoaEi6uNMuuXKeYcXM3gGUEQLzbDWGcFUdd3y49crtZK
$ git commit -a -m "gx publish 6.1.0"
[master 5c4d36c] gx publish 6.1.0
 2 files changed, 3 insertions(+), 2 deletions(-)

The release subcommand can be used to automate the above process. gx release <version> will do a version update (using the same inputs as the normal version command), run a gx publish, and then execute whatever you have set in your package.json as your releaseCmd. To get the above git commit flow, you can set it to: git commit -a -m \"gx publish $VERSION\" and gx will replace $VERSION with the newly changed version before executing the git commit.

Ignoring files from a publish

You can use a .gxignore file to make gx ignore certain files during a publish. This has the same behaviour as a .gitignore.

Gx also respects a .gitignore file if present, and will not publish any file excluded by it.

Repos

gx supports named packages via user configured repositories. A repository is simply an ipfs object whose links name package hashes. You can add a repository as either an ipns or ipfs path.

Usage

Add a new repo

$ gx repo add myrepo /ipns/QmPupmUqXHBxikXxuptYECKaq8tpGNDSetx1Ed44irmew3

List configured repos

$ gx repo list
myrepo       /ipns/QmPupmUqXHBxikXxuptYECKaq8tpGNDSetx1Ed44irmew3

List packages in a given repo

$ gx repo list myrepo
events      QmeJjwRaGJfx7j6LkPLjyPfzcD2UHHkKehDPkmizqSpcHT
smalltree   QmRgTZA6jGi49ipQxorkmC75d3pLe69N6MZBKfQaN6grGY
stump       QmebiJS1saSNEPAfr9AWoExvpfGoEK4QCtdLKCK4z6Qw7U

Import a package from a repo:

$ gx repo import events

Hooks

gx supports a wide array of use cases by having sane defaults that are extensible based on the scenario the user is in. To this end, gx has hooks that get called during certain operations.

These hooks are language specific, and gx will attempt to make calls to a helper binary matching your language to execute the hooks. For example, when writing go, gx calls gx-go hook <hookname> <args> for any given hook.

Currently available hooks are:

  • post-import
    • called after a new package is imported and its info written to package.json.
    • takes the hash of the newly imported package as an argument.
  • post-init
    • called after a new package is initialized.
    • takes an optional argument of the directory of the newly init'ed package.
  • pre-publish
    • called during gx publish before the package is bundled up and added to ipfs.
    • currently takes no arguments.
  • post-publish
    • called during gx publish after the package has been added to ipfs.
    • takes the hash of the newly published package as an argument.
  • post-update
    • called during gx update after a dependency has been updated.
    • takes the old package ref and the new hash as arguments.
  • post-install
    • called after a new package is downloaded, during install and import.
    • takes the path to the new package as an argument.
  • install-path
    • called during package installs and imports.
    • sets the location for gx to install packages to.

Package directories

Gx by default will install packages 'globally' in the global install location for your given project type. Global gx packages are shared across all packages that depend on them. The location of this directory can be changed if desired. Add a hook to your environments extension tool named install-path (see above) and gx will use that path instead. If your language does not set a global install path, gx will fallback to installing locally as the default. This means that it will create a folder in the current directory named vendor and install things to it.

When running gx install in the directory of your package, gx will recursively fetch all of the dependencies specified in the package.json and save them to the install path specified.

Gx supports both local and global installation paths. Since the default is global, to install locally, use --local or --global=false. The global flag is passed to the install-path hook for your extension code to use in its logic.

Using gx as a Go package manager

If you want (like me) to use gx as a package manager for go, it's pretty easy. You will need the gx go extensions before starting your project:

$ go get -u github.com/whyrusleeping/gx-go

Once that's installed, use gx like normal to import dependencies. You can import code from the vendor directory using:

import "gx/ipfs/<hash>/packagename"

for example, if i have a package foobar, you can import with gx it like so:

$ gx import QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa

And then in your go code, you can use it with:

import "gx/ipfs/QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/foobar"

Then simply set the environment variable GO15VENDOREXPERIMENT to 1 and run go build or go install like you normally would. Alternatively, install your dependencies globally (gx install --global) and you can leave off the environment variable part.

See the gx-go repo for more details.

Using gx as a Javascript package manager

Please take a look at gx-js.

Using gx as a package manager for language/environment X

If you want to use gx with a big bunch of repositories/packages please take a look at gx-workspace.

If you want to extend gx to work with any other language or environment, you can implement the relevant hooks in a binary named gx-X where the 'X' is the name of your environment. After that, any package whose language is set to 'X' will call out to that tools hooks during normal gx operations. For example, a 'go' package would call gx-go hook pre-publish during a gx publish invocation before the package is actually published. For more information on hooks, check out the hooks section above.

See also the examples directory.

Why is it called gx?

No reason. "gx" stands for nothing.

Getting Involved

If you're interested in gx, please stop by #gx and #ipfs on freenode irc!

License

MIT. Jeromy Johnson.

gx's People

Contributors

adamnovak avatar affankingkhan avatar anacrolix avatar arcalinea avatar bmwiedemann avatar chriscool avatar dgrisham avatar djdv avatar frrist avatar hackergrrl avatar hsanjuan avatar jesseclay avatar kalmi avatar kubuxu avatar lexrus avatar lion7 avatar magik6k avatar meyer9 avatar notslang avatar rht avatar richardlitt avatar ryanbreen avatar schomatis avatar stebalien avatar whyrusleeping avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

gx's Issues

gx hangs.

no idea what happened, now running gx init anywhere hangs.

jbenet @ lorien : ~/go/src/github.com/jbenet/go-multihash * master % gx init
^\SIGQUIT: quit
PC=0x484ab

goroutine 0 [idle]:
runtime.mach_semaphore_wait(0x1103, 0xc208012000, 0x110300000000, 0x11000000110000, 0x3e276, 0xc208012000, 0xc208012000, 0x45618, 0x3bba0, 0xdcadd0, ...)
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/sys_darwin_amd64.s:412 +0xb
semasleep()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/os_darwin.c:438 +0x16c
runtime.onM(0xdcadd0)
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:257 +0x68
runtime.mstart()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/proc.c:818

goroutine 5 [syscall]:
runtime.notetsleepg(0xdd5840, 0xffffffffffffffff, 0x1)
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/lock_sema.go:266 +0x8c fp=0xc20801d768 sp=0xc20801d728
runtime.signal_recv(0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/sigqueue.go:109 +0x135 fp=0xc20801d7a0 sp=0xc20801d768
os/signal.loop()
    /usr/local/Cellar/go/1.4.2/libexec/src/os/signal/signal_unix.go:21 +0x1f fp=0xc20801d7e0 sp=0xc20801d7a0
runtime.goexit()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1 fp=0xc20801d7e8 sp=0xc20801d7e0
created by os/signal.init·1
    /usr/local/Cellar/go/1.4.2/libexec/src/os/signal/signal_unix.go:27 +0x35

goroutine 1 [select]:
github.com/ipfs/go-ipfs/commands/http.(*client).Send(0xc20802b5b0, 0xf87be8, 0xc2080d4000, 0x0, 0x0, 0x0, 0x0)
    /Users/jbenet/go/src/github.com/ipfs/go-ipfs/commands/http/client.go:105 +0xfe9
github.com/whyrusleeping/ipfs-shell.(*Shell).ID(0xc20802b5d0, 0x0, 0x0, 0x0, 0x805440, 0x0, 0x0)
    /Users/jbenet/go/src/github.com/whyrusleeping/ipfs-shell/shell.go:55 +0x2d0
main.(*PM).CheckDaemon(0xc20800b600, 0x0, 0x0)
    /Users/jbenet/go/src/github.com/whyrusleeping/gx/main.go:41 +0x59
main.main()
    /Users/jbenet/go/src/github.com/whyrusleeping/gx/main.go:56 +0x2ae

goroutine 7 [chan receive]:
github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics.func·004()
    /Users/jbenet/go/src/github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics/metrics.go:321 +0x80
created by github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics.init·1
    /Users/jbenet/go/src/github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics/metrics.go:328 +0x76

goroutine 8 [select]:
net/http.(*persistConn).roundTrip(0xc2080cf600, 0xc20802b8b0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:1082 +0x7ad
net/http.(*Transport).RoundTrip(0xc208032090, 0xc2080d0f70, 0xc20803ba00, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:235 +0x558
net/http.send(0xc2080d0f70, 0xf86948, 0xc208032090, 0x3d, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:219 +0x4fc
net/http.(*Client).send(0xdca360, 0xc2080d0f70, 0x3d, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:142 +0x15b
net/http.(*Client).doFollowingRedirects(0xdca360, 0xc2080d0f70, 0xad7928, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:367 +0xb25
net/http.(*Client).Do(0xdca360, 0xc2080d0f70, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/client.go:177 +0x192
github.com/ipfs/go-ipfs/commands/http.func·001()
    /Users/jbenet/go/src/github.com/ipfs/go-ipfs/commands/http/client.go:90 +0x59
created by github.com/ipfs/go-ipfs/commands/http.(*client).Send
    /Users/jbenet/go/src/github.com/ipfs/go-ipfs/commands/http/client.go:102 +0xc15

goroutine 11 [IO wait]:
net.(*pollDesc).Wait(0xc2080b48b0, 0x72, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/fd_poll_runtime.go:84 +0x47
net.(*pollDesc).WaitRead(0xc2080b48b0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/fd_poll_runtime.go:89 +0x43
net.(*netFD).Read(0xc2080b4850, 0xc2080bc000, 0x1000, 0x1000, 0x0, 0xf86160, 0xc20802ba28)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/fd_unix.go:242 +0x40f
net.(*conn).Read(0xc20802c098, 0xc2080bc000, 0x1000, 0x1000, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/net.go:121 +0xdc
net/http.noteEOFReader.Read(0xf88df0, 0xc20802c098, 0xc2080cf658, 0xc2080bc000, 0x1000, 0x1000, 0xf74010, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:1270 +0x6e
net/http.(*noteEOFReader).Read(0xc20800b840, 0xc2080bc000, 0x1000, 0x1000, 0xc207ffd3f5, 0x0, 0x0)
    <autogenerated>:125 +0xd4
bufio.(*Reader).fill(0xc2080549c0)
    /usr/local/Cellar/go/1.4.2/libexec/src/bufio/bufio.go:97 +0x1ce
bufio.(*Reader).Peek(0xc2080549c0, 0x1, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/bufio/bufio.go:132 +0xf0
net/http.(*persistConn).readLoop(0xc2080cf600)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:842 +0xa4
created by net/http.(*Transport).dialConn
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:660 +0xc9f

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1

goroutine 12 [select]:
net/http.(*persistConn).writeLoop(0xc2080cf600)
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:945 +0x41d
created by net/http.(*Transport).dialConn
    /usr/local/Cellar/go/1.4.2/libexec/src/net/http/transport.go:661 +0xcbc

rax     0xe
rbx     0x7fff5fbfee70
rcx     0x7fff5fbfee28
rdx     0xc20801d6e8
rdi     0x1103
rsi     0x3
rbp     0x45570
rsp     0x7fff5fbfee28
r8      0x1003
r9      0x0
r10     0x30
r11     0x286
r12     0x169e7364d94dc
r13     0x16bced5508a78
r14     0x13eb9395d6282400
r15     0x10
rip     0x484ab
rflags  0x286
cs      0x7
fs      0x0
gs      0x0

need global too

i'd like to be able to setup my imports like:

ipfs/<hash>/pkgname
gx/<hash>/pkgname

so that there's one global location for stuff. and symlink to that.

(of course, we do need to handle the case where things are vendored locally too. but the global case is really nice to have)

rename "language"

The big appeal of gx to me is its agnostic nature: it provides package management and versioned dependencies happily and blindly.

"language" makes a deep assumption: that you're writing a package manager for a programming language. Why not "ecosystem" or "namespace"? gx doesn't know about semantics (rightly): there could be ten different and equally valid packaging styles for Java -- but only one lucky developer wins that language namespace.

Let's keep gx beautifully ignorant: blindly support all ecosystems!

lowercase json keys

to be npm package.json compatible, the json keys must be lowercase.

now, it outputs uppercase:

> gx init
initializing package go-multiaddr...
> cat package.json
{
  "Name": "go-multiaddr",
  "Files": null,  // omit 
  "Version": "",
  "Dependencies": null,   // should be {}
  "Bin": "", // omit
  "Build": "", // omit
  "Test": "", // omit
  "Language": "" // omit
}

also want to:

  • omit empty keys.
  • always have a version

gx is using itself for its deps. cannot build.

gx is using itself for its deps. cannot build.

jbenet @ lorien : ~/go/src/github.com/whyrusleeping/gx * master % go install
main.go:9:2: cannot find package "QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/cobra" in any of:
    /usr/local/Cellar/go/1.4.2/libexec/src/QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/cobra (from $GOROOT)
    /Users/jbenet/go/src/QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/cobra (from $GOPATH)
jbenet @ lorien : ~/go/src/github.com/whyrusleeping/gx * master % ls
Makefile  README.md  get.go  gx*  log.go  main.go  package.json  pkgfile.go  publish.go  vendor/
jbenet @ lorien : ~/go/src/github.com/whyrusleeping/gx * master % cat package.json
{
  "Name": "gx",
  "Files": [
    "README.md",
    "get.go",
    "main.go",
    "pkgfile.go",
    "publish.go"
  ],
  "Version": "",
  "Dependencies": [
    {
      "Author": "",
      "Name": "cobra",
      "Hash": "QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa"
    }
  ],
  "Bin": "",
  "Build": "",
  "Test": "",
  "Language": "go"
}

go/src/runtime/panic1.go:11: too many errors

go get -u github.com/whyrusleeping/gx-go

# runtime
go/src/runtime/os2_linux_generic.go:12: _SS_DISABLE redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:8
go/src/runtime/os2_linux_generic.go:13: _NSIG redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:9
go/src/runtime/os2_linux_generic.go:14: _SI_USER redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:10
go/src/runtime/os2_linux_generic.go:15: _SIG_BLOCK redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:11
go/src/runtime/os2_linux_generic.go:16: _SIG_UNBLOCK redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:12
go/src/runtime/os2_linux_generic.go:17: _SIG_SETMASK redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:13
go/src/runtime/os2_linux_generic.go:18: _RLIMIT_AS redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:14
go/src/runtime/os2_linux_generic.go:24: sigset redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:20
go/src/runtime/os2_linux_generic.go:26: rlimit redeclared in this block
    previous declaration at go/src/runtime/os2_linux.go:22
go/src/runtime/panic1.go:11: paniclk redeclared in this block
    previous declaration at go/src/runtime/panic.go:535
go/src/runtime/panic1.go:11: too many errors
  • go 1.6
  • ubuntu 14.04

Issues installing

🐕   go get -d github.com/ipfs/go-ipfs
11:49 ~/src/http-api-spec (feature/name) * 🐕  cd $GOPATH/src/github.com/ipfs/go-ipfs
11:49 ~/gocode/src/github.com/ipfs/go-ipfs (master) 🐕  make install
go get -u github.com/whyrusleeping/gx
go get -u github.com/whyrusleeping/gx-go
gx --verbose install --global
make: gx: No such file or directory
make: *** [deps] Error 1

gx import hanging

I have ipfs daemon running. I can cat things and get things from hashes.

When I try and use gx to import a package, I get:

$ gx --verbose import QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr
runhook(install-path): No gx helper tool found for haskell
  - QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr not found locally, fetching into vendor/gx/ipfs/QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr
  - fetching QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr via ipfs api

And then a hang. I've done an strace and can see that gx sends a POST to ipfs and waits indefinitely for a response. If I kill the daemon I can see some of the requests it wants to do:

ERROR: from shell.Get():  get: context canceled
retrying fetch QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr after a second...
ERROR: from shell.Get():  Post http://127.0.0.1:5001/api/v0/get?arg=QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr&encoding=json&stream-channels=true&: dial tcp 127.0.0.1:5001: getsockopt: connection refused
retrying fetch QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr after a second...
ERROR: from shell.Get():  Post http://127.0.0.1:5001/api/v0/get?arg=QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr&encoding=json&stream-channels=true&: dial tcp 127.0.0.1:5001: getsockopt: connection refused
ERROR: (install): failed to fetch package: QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr: Post http://127.0.0.1:5001/api/v0/get?arg=QmaDFJvcHAnxpnMwcEh6VStYN4v4PB4S16j4pAuC2KSHVr&encoding=json&stream-channels=true&: dial tcp 127.0.0.1:5001: getsockopt: connection refused

Doing a curl for those resources also waits idefinitely.

File atime still broken on Illumos

jon@abydos:~/go/src/github.com/ipfs/go-ipfs > gmake gx_upgrade
go get -u github.com/whyrusleeping/gx
# github.com/jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo
../../jbenet/go-multiaddr-net/Godeps/_workspace/src/github.com/anacrolix/missinggo/atime.go:10: undefined: fileInfoAccessTime
Makefile:26: recipe for target 'gx_upgrade' failed
gmake: *** [gx_upgrade] Error 2
jon@abydos:~/go/src/github.com/ipfs/go-ipfs > date
March 25, 2016 05:36:12 PM UTC

I'm pretty sure this is fixed upstream.

Structure and File-names not generally compatible

If you are only planning on using gx for node and go, then it works fine.

however other languages have different requirements for folder structures and limits to file name (python stands out as an example).

If you want it to be a "general any language" package manager, you need to find an elegant way to deal with this (language specific plugins?)

does not handle directories

> gx publish
error: Post http://localhost:5001/api/v0/add?enc=json&stream-channels=true: read /Users/jbenet/go/src/github.com/jbenet/go-multihash/gen: is a directory

remove link/unlink commands + functionality

tl;dr: let's remove link/unlink from gx, and leave naming semantics to environment-specific toolling. This lets gx not need to try and find a universal solution for naming that avoids conflicts and works for all possible environments. If gx only saves packages by their multihash we're guaranteed not to cause conflicts.

13:05 <noffle> what are your thoughts on nixing link/unlink?

13:06 <whyrusleeping> i agree with you
13:06 <whyrusleeping> but i want a way of standardizing 'nice' names...

13:07 <noffle> I agree. multihashes kind of suck. but gx makes ipfs a first-class citizen that's exposed: we don't need to fret showing users the hash
13:07 <noffle> I think most subtools will just do what you're currently doing
13:07 <noffle> it'll be trivial with the hook callback, if it provides hash+name+semver
13:08 <noffle> I don't think standardization is possible, since there are already many existing ecosystems that ALREADY conflict

13:08 <whyrusleeping> hrm... yeah. i guess all we need to do is provide the hash to the subtools
13:08 <whyrusleeping> since the rest of the info is in the package

13:09 <noffle> true

13:09 <whyrusleeping> okay fine, no link command
13:09 <whyrusleeping> (this will make blame happy too)

How to set up a development environment?

When I clone the repo and run go build, I get:

main.go:13:2: cannot find package "github.com/blang/semver" in any of:
    /usr/local/go/src/github.com/blang/semver (from $GOROOT)
    /Users/anovak/Documents/Workspace/Go/src/github.com/blang/semver (from $GOPATH)
main.go:14:2: cannot find package "github.com/codegangsta/cli" in any of:
    /usr/local/go/src/github.com/codegangsta/cli (from $GOROOT)
    /Users/anovak/Documents/Workspace/Go/src/github.com/codegangsta/cli (from $GOPATH)
main.go:15:2: cannot find package "github.com/whyrusleeping/gx/gxutil" in any of:
    /usr/local/go/src/github.com/whyrusleeping/gx/gxutil (from $GOROOT)
    /Users/anovak/Documents/Workspace/Go/src/github.com/whyrusleeping/gx/gxutil (from $GOPATH)
main.go:16:2: cannot find package "github.com/whyrusleeping/stump" in any of:
    /usr/local/go/src/github.com/whyrusleeping/stump (from $GOROOT)
    /Users/anovak/Documents/Workspace/Go/src/github.com/whyrusleeping/stump (from $GOPATH)

It looks like, according to the Internet, the solution is to run go get ./..., but then I'm stuck using the Github version of gxutil, so if I were to want to make a change in that package, I'm not sure how I'd do that.

It also looks like my checkout has to be under $GOPATH/src.

This is all probably obvious information for anyone who has ever used Go before, but I haven't, so I would appreciate a simple step-by-step guide in the README for getting set up. Something like:

cd $GOPATH/src
git clone [email protected]:whyrusleeping/gx.git
cd gx
go get ./...
go build

Is that actually the right procedure to get set up? How should I extend it if I also want to tinker with a dependency?

If this is the Right Way, I'll open a PR.

Tags or version info

As I packaged gx and gx-go onto AUR automated way of getting version info from source files would be great.

I could sed my way through the source file but dedicated file with version info or git tags would be much better.

gx view

Much like npm view, so tooling can get fields out of package.json trivially:

$ gx view Qmfoobarfoobarfoobarfoobar name`
replication-stream

$ gx view Qmfoobarfoobarfoobarfoobar version`
4.3.0

$ gx view Qmfoobarfoobarfoobarfoobar semver-name`
[email protected]

Does not build using make

GOPATH=/home/tperson:/home/tperson/src/github.com/whyrusleeping/gx/pkg
go install
main.go:10:2: cannot find package "QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/cobra" in any of:
    /home/tperson/.go/src/QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/cobra (from $GOROOT)
    /home/tperson/src/QmR5FHS9TpLbL9oYY8ZDR3A7UWcHTBawU1FJ6pu9SvTcPa/cobra (from $GOPATH)
Makefile:8: recipe for target 'install' failed
make: *** [install] Error 1

To get around for now you need to append the vendor directory to your GOPATH.

env GOPATH=$GOPATH:(pwd)/vendor make install

Or $(pwd) for those not in fish

Pass --global flag to postinstall hook

I am working on gx-js. In node as part of the post install hook the gx-js hook will need to link the bin file to either $pwd/node_modules/.bin in the local install folder or from NODE_PATH/../../lib/node_modules to NODE_PATH/../bin for a global install. It's problematic to assume that it was a global install based on only on the shape of the path to the newly installed module provided as the current arg to the hook. Since we need to do slightly different things it would be helpful to have that flag as an arg to post install too.

pathing

Alright, We need to make a decision on what paths should look like so I can move forward without having to worry about going back and rewriting everything.

currently, installing packages locally goes into vendor/gx/<hash>. Previously it was just vendor/<hash>
Globally installed packages get installed under $GLOBAL_ROOT/gx/<hash>.

@jbenet has suggested gx/ipfs/<hash> for protocol nesting.

Since the global root will be language dependent anyways ($GOPATH/src for go). We should probably do something similar for the local path, and default to something like gx/ipfs/<hash>. That way go packages can still specify to install under vendor/gx/ipfs/<hash>. Alternatively (go specific thing ahead), we can skip the vendor experiment thing altogether, and just have the paths be like how godep does them. (the go vendor experiment really did us fewer favors that I would have liked)

cc @noffle @diasdavid

Install and Postinstall hooks may need to know the root install target.

This is like a node thing, I think, maybe useful with other lang specific sub tools.

A give node module may declare a "bin" field like so in the package.json

  "bin": "./bin/cli.js"

And that will be symlinked either to node_modules/.bin if a local install or /usr/local/bin if a global install.

However if we gx install gx-foo-js and gx-foo-js depends on gx-quux-js and both declare "bin"s then the gx postinstall hook has no way to determine which one was the "root" target of the gx install command, because we only really want to symlink the binary for direct imports or installs not every package.

By the way, gx-js is coming along, thanks for the --global flag that worked great.

gx install <pkg> -- does nothing

> gx install QmXrnpeF2R5k8StJXCPQjbAYYrjF23qAxpgyfnSGge43Z5
> git status
> ls vendor/src
>

no change. nothing downloaded, and package.json not changed. and no error.

Distribute over IPFS

It'd be useful to have releases on IPFS, so that we don't need go get for bootstrapping gx.

don't finalize partial downloads

when fetching dependencies, we should fetch them into a temp-ish directory (like HASH.tmp or HASH.partial) and then only rename them to the proper name once the download is complete.

Document .gxignore

It looks like there's support for a .gxignore file. How does that work? It should be documented.

Integrating gx: CLI sub-commands and hooks

As per the Unix philosophy, gx should try to defer as many ecosystem-specific policy decisions and logic to external programs, focusing on sane defaults rather than worrying about what semantics make sense for any one given ecosystem.

Sub-Commands

It sounds like support for git-style subcommands is the way to go:

$ gx java build

would execute gx-java, assuming it's on my $PATH somewhere.

Hooks

gx could expose a variety of git-like hooks:

  • post-import
  • pre-publish
  • post-publish
  • post-update

To issue these hooks to external tooling, gx would call out to an ecosystem-specific tool could using the shell:

gx [ecosystem] hook post-import

The tool for the given ecosystem would receive the hook and post-import CLI arguments, do or don't do work, and return an exit code. gx could then use that exit code to make decisions, like not permitting a publish on non-zero exit codes for pre-publish.

Node.js support

It'd be cool if there was a way to have downloaded packages form the node_modules file tree that's required for Node. Has there been any effort going in this direction with something using the hooks yet?

The reason I bring this up is that people seem pretty pissed at NPM, and this could be a great way to get a large number of users for the package.

Index out of range with `gx view gxDependencies.name`

When running the command in go-ipfs I get:

> gx view gxDependencies.name
panic: runtime error: index out of range

goroutine 1 [running]:
main.glob.func8(0xc8200a43c0)
        /home/utilisateur/gocode/src/github.com/whyrusleeping/gx/main.go:633 +0xc52
github.com/codegangsta/cli.Command.Run(0x86e400, 0x4, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8c81e0, 0x18, 0x0, ...)
        /home/utilisateur/gocode/src/github.com/codegangsta/cli/command.go:179 +0x1397
github.com/codegangsta/cli.(*App).Run(0xc8200906e0, 0xc82000a360, 0x3, 0x3, 0x0, 0x0)
        /home/utilisateur/gocode/src/github.com/codegangsta/cli/app.go:196 +0x1386
github.com/codegangsta/cli.(*App).RunAndExitOnError(0xc8200906e0)
        /home/utilisateur/gocode/src/github.com/codegangsta/cli/app.go:207 +0x54
main.main()
        /home/utilisateur/gocode/src/github.com/whyrusleeping/gx/main.go:90 +0x642

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
        /usr/local/go/src/runtime/asm_amd64.s:1721 +0x1

gx for scripting languages

As in scripting languages in most cases there is no single point with imports (like in go or C) not there is one way to call function that imports (simple sed won't work).

My idea was to include one liner (not possible in all languages) which would wrap native dependency resolution and return gx dependencies. It isn't the cleanest solution but it works.
Example:

local require=require do local o,m=require,{["small-json"]="vendor/gx/ipfs/QmStLN3uVZ5RuaTNLBnfdFzp2tsCrVRP4W8WTTbG8jKseX/small-json",["log"]="vendor/gx/ipfs/QmXoUodR1YXF8AB28qz65c3k2bkUnmZg59VZzBh78SkkxM/log"}require=function(n)_G[n]=o(m[n] or n) return _G[n]end end--$$gx-header

which expands to:

local require = require
do
  local oldrequire = require
  local map = {
    ["small-json"] = "vendor/gx/ipfs/QmStLN3uVZ5RuaTNLBnfdFzp2tsCrVRP4W8WTTbG8jKseX/small-json",
    ["log"] = "vendor/gx/ipfs/QmXoUodR1YXF8AB28qz65c3k2bkUnmZg59VZzBh78SkkxM/log"
  }
  require = function (module)
    _G[module] = oldrequire(map[module] or module)
    return _G[module]
  end
end

where map variable is generated from package.json
Its size for sure can be compressed even more.

This header would be added to all Lua files by gx hooks.
If anyone can come up with cleaner or nicer solution for scripting languages, it would be awesome.

open it up?

hey @whyrusleeping we should open this up, i wanna start using it and playing with it. feel free to open it up under protocol/ or under whyrusleeping/ or whatever you want.

once you open it up, i'll start using it + compiling feedback and post it in the repo. I'll have it as criteria:

  • MUST handle go-specific packaging/distribution concerns well
  • SHOULD handle go-specific module system concerns well[0]
  • MAY handle packaging/distribution concerns well
  • MAY handle module system concerns well

[0] go get's failure as a module system stems from not realizing a "module system" is different from a "package distribution tool". And this distinction is where npm shines (node packaged modules).

libgx

I'd like to see gx be made into a powerful dependency resolution and retrieval mechanism, to be composed as a library within more specialized CLI (or GUI) tooling. This effectively splits policy from mechanism: gx is really good at retrieving package blobs from IPFS and managing dependencies, but directory structure and other policy varies by language/ecosystem.

GX Subtools

If you are working on a language specific subtool for gx, please let us know here so we can link to it in the readme.

files considered harmful

  "Files": [
    "LICENSE",
    "README.md",
    "codec.go",
    "doc.go",
    "interface.go",
    "multiaddr.go",
    "multiaddr_test.go",
    "package.json",
    "protocols.csv",
    "protocols.go",
    "util.go"
  ],

is a bad idea because it strongly encourages the developer to have a different dev environment than the consumers of the package, which invariably leads to lack of parity, testing, and correctness.

The approach npm takes is the opposite. it adds everything, except things in .gitignore OR .npmignore. I think a .gxignore similarly makes sense.

gx-bin

  • I'd like to be able to install binaries with gx, to a common place.
  • both local (in repo) and global (system). Just like npm install and npm install -g
  • This could be done with a gx-bin tool.
  • want to be able to generate binaries for a bunch of different platforms (arch x os) and have gx install the right one for the local platform. Like gobuilder-cli but for everything not just go.
  • this would make it easier for us to install ipfs toolchain things, like fs-repo-migrations, ipfs-update, and so on.
  • maybe i should just use nix.

Type conflicts between normal and gx imports of the same package

Hey,

Im not using gx myself, but Im trying to use ipfs as a library. I tend to run into the following issuse: When using the same package twice, once as normal import from github and once as gx import, go will spit out an error when mixing those types:

/tmp/mh/mh.go:12: cannot use b (type 
"gx/ipfs/QmYf7ng2hG5XBtJA3tN34DQ2GUN5HNksEw1rLDkmr6vGku/go-multihash".Multihash) 
as type "github.com/jbenet/go-multihash".Multihash in assignment

See this gist for the code producing this error.

This usually happens when using a function from ipfs or libp2p that returns a multihash, multiaddr (etc.) and I need to store those in my own structures. I could probably resolve that by being forced to use gx myself or by brute force: Convert all types manually into my own types. Both solution would not be favorable for me.

I might be missing something, but gx seems to make the usage of ipfs as library harder... :-(

golang: ability to import other people's packages

other packages often dont have gx package.jsons. it's annoying to have to go in there and define one. maybe should be able to have a way to import any package, and the version gets set to the full hash in that case.

gx install on windows fails

Looks like more path issues on Windows when doing "gx install"

ERROR: open vendor\gx\ipfs\C:\MyProject\MyPath: The filename, directory name, or volume label syntax is incorrect.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.