{"action":"created","issue":{"url":"https://api.github.com/repos/constabulary/gb/issues/49","labels_url":"https://api.github.com/repos/constabulary/gb/issues/49/labels{/name}","comments_url":"https://api.github.com/repos/constabulary/gb/issues/49/comments","events_url":"https://api.github.com/repos/constabulary/gb/issues/49/events","html_url":"https://github.com/constabulary/gb/issues/49","id":73570803,"number":49,"title":"[RFC] Adding support for creating gb projects that don't contain main packages","user":{"login":"davecheney","id":7171,"avatar_url":"https://avatars.githubusercontent.com/u/7171?v=3","gravatar_id":"","url":"https://api.github.com/users/davecheney","html_url":"https://github.com/davecheney","followers_url":"https://api.github.com/users/davecheney/followers","following_url":"https://api.github.com/users/davecheney/following{/other_user}","gists_url":"https://api.github.com/users/davecheney/gists{/gist_id}","starred_url":"https://api.github.com/users/davecheney/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/davecheney/subscriptions","organizations_url":"https://api.github.com/users/davecheney/orgs","repos_url":"https://api.github.com/users/davecheney/repos","events_url":"https://api.github.com/users/davecheney/events{/privacy}","received_events_url":"https://api.github.com/users/davecheney/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/constabulary/gb/labels/enhancement","name":"enhancement","color":"84b6eb"},{"url":"https://api.github.com/repos/constabulary/gb/labels/help%20wanted","name":"help wanted","color":"159818"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":4,"created_at":"2015-05-06T09:30:40Z","updated_at":"2015-06-10T02:21:36Z","closed_at":null,"body":"This is a blanket issue to cover questions on the go-pm mailing list and other issues. \r\n\r\n# Supporting gb projects that don't have a main package\r\n\r\nCurrently a `gb` project is defined as a collection of packages and main packages (commands), along with supporting source code in `vendor/src/`. \r\n\r\nAt the GDG presentation in Berlin in April I said that `gb` was not suitable for libraries (projects consisting of non main packages, to use an imprecise definition), after reflecting on this for a few days I think this restriction may have been premature and probably motivated by trying to simplify the story for the GDG audience.\r\n\r\nSpecifically there is nothing preventing a library author using `gb`, and in fact many of the reasons why a library author would want to take advantage of the reproducibility guarantees that a `gb` project attempts to offer.\r\n\r\n# Distinguishing between projects and library projects \r\n\r\nIn principal a `gb` project, and a `gb` library project (need to find a better description) are the same, they both contain some code in `$PROJECT/src/`, they both may contain some supporting dependencies  in `vendor/src/`. The only remaining point of differentiation is `gb build` executed in the former may produce some output in `$PROJECT/bin/`, while the latter most likely will not.\r\n\r\nIn short, this prohibition was short sighted and unnecessary. \r\n\r\nHowever, with this prohibition relaxed, a new question arises: how can one `gb` project consume another `gb` project as a dependency ? It turns out that this isn't a very difficult proposition, but it is regrettably manual at the moment. Consider this scenario, `mongodb/` is the project root of some library, `twitter` is the project root of a `gb` project that consumes `mongodb`'s packages as a dependency. The names are completely arbitrary.\r\n\r\n```\r\nmongodb/\r\n    src/\r\n        client/\r\n            client.go\r\n    vendor/\r\n        src/\r\n            bson/\r\n                bson.go\r\n            gocheck/\r\n                tests.go\r\n```\r\n\r\n```\r\ntwitter/\r\n    src/\r\n        cmd/\r\n            twitter/\r\n                main.go\r\n    vendor/\r\n        src/\r\n```\r\n\r\n`mongodb` and `twitter` are developed separately, they live in different respositories. The `mongodb` client has a dependency on `bson`, and includes its source in its' `vendor/src/` directory. `mongodb` also has a dependency on `gocheck` for tests.\r\n\r\nThe process for vendoring `mongodb` into `twitter/vendor/src/` would be to copy the contents of `mongodb/src/*` into `twitter/vendor/src/` and also _selectively_ copying `mongodb/vendor/src/*` into `twitter/vendor/src/`. The project owner of `twitter` may choose to omit the `gocheck` dependency of `mongodb`, of they may choose to include it for completeness.\r\n\r\n# Open issues\r\n\r\nThe process described above is not difficult, but it does require the package owner to be cognoscente of their actions when importing new dependencies into their project. Automating this initial import with tools is difficult at the moment due to a lack of version information in Go code in general (see #20 for a distinction between _version_ and _revision_). Automating the orderly upgrade of a set of vendored dependencies is more difficult again.\r\n\r\nTackling these issues are outside the scope of this specific bug, and arguably outside the code mandate of `gb` -- it just provides the mechanism to work with a \"project\" of Go code, it is mute on how that source is assembled -- but feels like ample fuel for a plugin that tackles these complicated issues."},"comment":{"url":"https://api.github.com/repos/constabulary/gb/issues/comments/110560812","html_url":"https://github.com/constabulary/gb/issues/49#issuecomment-110560812","issue_url":"https://api.github.com/repos/constabulary/gb/issues/49","id":110560812,"user":{"login":"bruth","id":515142,"avatar_url":"https://avatars.githubusercontent.com/u/515142?v=3","gravatar_id":"","url":"https://api.github.com/users/bruth","html_url":"https://github.com/bruth","followers_url":"https://api.github.com/users/bruth/followers","following_url":"https://api.github.com/users/bruth/following{/other_user}","gists_url":"https://api.github.com/users/bruth/gists{/gist_id}","starred_url":"https://api.github.com/users/bruth/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/bruth/subscriptions","organizations_url":"https://api.github.com/users/bruth/orgs","repos_url":"https://api.github.com/users/bruth/repos","events_url":"https://api.github.com/users/bruth/events{/privacy}","received_events_url":"https://api.github.com/users/bruth/received_events","type":"User","site_admin":false},"created_at":"2015-06-10T02:21:36Z","updated_at":"2015-06-10T02:21:36Z","body":"From experience in other languages, secondary dependencies of explicit dependencies in a project are included as is unless the same dependency is already present. Many of the existing dependency/manifest files allow for specifying a *range* of versions (revisions) that are valid for the library to behave correctly. This of course conflicts with the current notion of vendoring since a specific snapshot of the dependency is versioned with the source code (as well as the code at a particular version being available). There may need to be a trade-off defined for libraries that allow a range of versions to pull those dependencies in dynamically. The basic logic would be:\r\n\r\n- Fetch project dependency\r\n- Check if project has dependencies that overlap with a dependency's dependencies\r\n- Check if the version requirements conflict between the two\r\n- If not, fetch the most recent common version\r\n- Otherwise return an error and push it on the developer to update their dependency version locally or contact the library maintainer to see if the version requirement is necessary.\r\n\r\nThe bottom line is that libraries are generally not as strict with dependency versions as projects, so that needs to be considered when *vendoring* a library in the `gb` structure. A project's manifest file could include a dependency's dependencies with the version [ranges] specified."}}