1

I'm relatively new to Golang, having used Node.JS with AngularJS on a previous project, and am having trouble with Golang being very opinionated about project structure. Our Go code exists in a repository that also contains our HTML, CSS, and JS code, so that our "web UI" is a single checkout. The Go server serves up static pages to let AngularJS do the heavy lifting client-side, and provides a fairly complex RESTful API for interacting with a piece of embedded hardware. We use local includes in the Go server code to workaround the fact that the code isn't actually in GOPATH. The folder structure is roughly (subfolders not shown):

/ <-- repo root, checked out wherever you want (not in GOPATH) fonts/ scripts/ <-- all the AngularJS code server/ <-- all the Go code styles/ views/ <-- all the HTML code

I'm now working with the go-swagger library to generate a Swagger spec from comments in our Go server code, since the Swagger UI provides a convenient UI for interacting with our server API. However, I've found that a significant portion of the go-swagger parser can't be used if your code is not within GOPATH. I can get go-swagger to work if I copy the server folder into the GOPATH src directory and run it there, but I obviously don't want to do that every time I update the API or add new routes.

I imagine that I will have to make some changes either to our folder structure or our build process, but I'd like to understand the most logical way forward. Ideally, we would add a new task to our Gruntfile to generate the swagger spec by calling into go-swagger, and that spec would be copied into the default location for Swagger UI so that we can serve up the correct API spec with each build. I understand how the task should operate, but it doesn't work with our current project structure. So:

  • Should we break the Go server code into its own repo that we check out in GOPATH? We have other tools (like ffjson) that are also unhappy with our Go code existing outside of GOPATH, so perhaps this is worth the effort to update our build process to handle.
  • Is there a way to modify GOPATH (or add to it like PATH) such that go-swagger (and ffjson) can work in our existing repo structure? This seems like the easiest path, if it's possible. I've tried checking out our "UI" repo in GOPATH, but that didn't work initially (perhaps it would work if I updated our imports to use the arbitrary paths from the repo root to the server folders).
  • Something else entirely? As I said, I'm pretty new to Go, and this project already existed for a few years when I came on board, so I'm not familiar with the ins and outs of Go just yet.
iamtheddrman
  • 623
  • 5
  • 16
  • Why not just move your entire project as-is into your GOPATH? You shouldn't have to break things up. – Gavin Jul 12 '17 at 14:05
  • When I first tried it, I got an error about not using local imports in GOPATH, so I removed the "./" and got a different error. Perhaps it would work if I used the complete path starting from the GOPATH root, but then it would require that everyone use the exact same folder name for their UI checkouts. That would also mean a single UI checkout at a time, when we sometimes have to work in multiple branches. – iamtheddrman Jul 12 '17 at 14:21
  • I tried checking out just a subfolder from git (where the folder name would rarely, if ever, change) and that seems to work for both our existing build and running ffjson and go-swagger. So that's a potential solution, but I would prefer a solution that doesn't require me to enforce the checkout of a subfolder of a repo into GOPATH, and the associated import changes. This is a local project that will never be hosted, so there is no requirement to be in GOPATH except for the tools we're using. – iamtheddrman Jul 12 '17 at 14:37
  • 3
    In Go development everything assumes your project is in GOPATH. If you find a solution this time, you might end up with another problem tomorrow. – TehSphinX Jul 12 '17 at 14:46
  • 1
    I totally agree with @TehSphinX you should move your project within GOPATH . If you have issues with dependecies, I suggest you to use dependency managment tool like `golang/dep` https://github.com/golang/dep – Raimondas Kazlauskas Jul 12 '17 at 14:57
  • You could have the restful service built in Go (and have that code in your Go path) and maybe just bundle the Angular app elsewhere and serve it with for instance nginx. That way you could have a folder `X` for your project with `X/frontend` the actual frontend code and `X/backend` a symlink to your backend in the GOPATH. That way your code stays organised and you're not fighting against the Go conventions. – Vincent van der Weele Jul 12 '17 at 14:59
  • So when developing a web server using Go (which seems to be a common use case), do developers typically just have all of their HTML/CSS/JS code also in GOPATH? That seems really odd, but I suppose that's better than Vincent's alternative of symlinks and tons of build infrastructure that's bound to be fragile. How do people cope with builds for different branches of Go code on something like Jenkins? We normally have workspaces for that, so perhaps we could set GOPATH to point to our workspace? – iamtheddrman Jul 12 '17 at 15:05
  • As of Go 1.11 you can use modules and escape the GOPATH – Ezequiel Muns Jan 08 '21 at 16:08

0 Answers0