View package documentation locally in a browser - go

I want to see locally how my package documentation will look. That is, I want to see the same kind of thing you see on godoc.org, but locally.
I have a simple example folder locally, but I can't get it to work. It correctly outputs text documentation:
~/code/go/gonotes (master) $ godoc .
PACKAGE DOCUMENTATION
package gonotes
import "."
FUNCTIONS
func Blah()
Here is header
Blah is function being use to test:
- go documentation
- blah like things
It is nice
But if I run godoc -http=:6060, and navigate to http://localhost:6060/, I see essentially the same content I'd see on the golang.com homepage. http://localhost:6060/gonotes displays
lstat $GOROOT/gonotes: no such file or directory
Am I misunderstanding how the -http works? Is there any way to preview the http version of my docs locally?
UPDATE
I was able to get it to appear by copying the files into src/gonotes and then running:
GOPATH=/Users/jonah/code/go/gonotes godoc -http=:6060
so that the actual files were available at /Users/jonah/code/go/gonotes/src/gonotes.
This has the side effect of not showing any of the Third part libs installed in my default GOPATH, so I'd still like to find a solution that just allows me to add the current directory, as is, without adding src/curdir to it, and still have it show up.

In GOPATH mode
godoc -http will serve doc of all available packages, including the standard library. Worry not, your own packages are amongst them, just look again. As a shortcut, just type http://localhost:6060/pkg/your/package.
In module-aware mode
GOPATH and modules are mutually exclusive, see Go Modules does not recognize files under GOPATH. The godoc tool is not module-aware, and it is being deprecated (see deprecation warning), so for now if you want to see your package docs of modules locally in godoc, you have to resort to putting their sources in an src folder.
"Workaround" for seeing docs of module's:
Put the repo in a folder like /some/folder/src
Start godocs with godoc -goroot=/some/folder -http=:6060
See related issue: support Go modules
Also groups discussion: Is the go 1.11 godoc tool 'module-aware'?

Related

Go linter in VS code not working for packages across multiple files?

I have installed the Go extension (version 0.11.4) in Visual Studio Code on MacOS:
However, I find that the linter does not 'pick up' functions defined in the same package, but in different files. For example, if I create in the same directory a file foo.go with
package foobar
import "fmt"
func main() {
fmt.Println(SayHello())
}
and a file bar.go with
package foobar
func SayHello() string {
return "Hello, world!"
}
then in foo.go I get a linter error that SayHello is an undeclared name:
I've read about a similar issue here (https://github.com/golang/lint/issues/57), but since that issue is five years old I figured it might be fixed by now? Or does golint simply not work across multiple files?
[The original answer is outdated; here is up-to-date information provided by the vscode-go maintainers. The updated answer is now marked as "Recommended" in the Go collective]
The plugin has changed a lot since 2019.
In 2021, Go Modules became the default which may have changed how the program is built and analyzed.
The vscode-go plugin uses gopls as the language server by default. Note that in 2019, there were two different language servers and gopls was still in experimental mode.
golint was deprecated.
If you still have a similar issue, it's likely that you are seeing a different problem.
Please check the followings:
Do you have go.mod? Otherwise, initialize your working module and restart the language server or reload the window.
Is the go.mod file in the root directory of your workspace? See gopls workspace setup
guide for complex setup.
Do you use build tags or other build constraints? Then see issue 29202. You may need to configure "go.buildTags" or "go.buildFlags".
If you expect lint errors from linters like staticcheck, golangci-lint, ..., check "go.lintOnSave" is set to the right scope.
If you notice that restarting the language server ("Go: Restart Language Server" command) fixes your issue, that's a gopls bug. Please consider to file an issue in github.com/golang/vscode-go following the troubleshooting guide.
Otherwise, please open a new question with details.
----- Original answer -------
I faced same problem. I found that I got into this problem after enabling "Go language server" which is an experimental feature. I disabled it in VS code settings->Go Configuration and after that the problem went away.
Update VS Code Go Tool might help.
Command + Shift + P -> Go: Install/update tools
Install all tools and restart VS Code.
May 2022 update:
This solution only works if you haven't installed the helper tools. Normally after you installed these packages it'll work right away with the default configuration, if you still have a problem, take a look at the answer above.
The cause of this warning for me was the setting go.lintOnSave, which was set to file. Changing the value to package made the linter correctly pick up the types defined in other files.
For people who ended up here:
The plugin has changed a lot since 2019.
In 2021, Go Module became the default which may have changed how the program is built and analyzed.
The vscode-go plugin uses gopls as the language server by default. Note that in 2019, there were two different language servers and gopls was still in experimental mode.
golint was deprecated.
If you still have a similar issue, it's likely that you are seeing a different problem.
Please check the followings:
Do you have go.mod? Otherwise, initialize your working module and restart the language server or reload the window.
Is the go.mod file in the root directory of your workspace? See gopls workspace setup
guide for complex setup.
Do you use build tags or other build constraints? Then see issue 29202. You may need to configure "go.buildTags" or "go.buildFlags".
If you expect lint errors from linters like staticcheck, golangci-lint, ..., check "go.lintOnSave" is set to the right scope.
If you notice that restarting the language server ("Go: Restart Language Server" command) fixes your issue, that's a gopls bug. Please consider to file an issue in github.com/golang/vscode-go following the troubleshooting guide.
Otherwise, please open a new question with details.
Update Install/update tools for GO
Open your code as main project in VS Code and avoid multiple projects/workspace in the same VS Code.
**
Single Project VS Code
**
**
Avoid Multiple Project in VS Code
**
If you run across this and are NOT using modules, then adding "go.useLanguageServer": false will disable gopls and return you to your former environment. (meaning vscode will now recognize functions and structures defined in multiple files in the same package)
In my case it was a missing go.mod file. I fixed with the following command:
go mod init example.com/myProject/myModule
Of course you should use a more reasonable module name.
Make clean uninstall of vscode and then it's work fine again...
add sudo if you needed to
rm -rf $HOME/Library/Application\ Support/Code
rm -rf $HOME/.vscode
Remove vscode from application
Download vscode and install again
One possible reason:
If you are referencing a function/variableis declared in a test file (*_test.go) from a non test file, this error would be thrown.
In my case, I just restarted VS Code and the error went away.
After almost pulling my hair out, I found that linting was working but I had many files with errors. I haven't yet found the hierarchy followed but fixing problems in one file subsequently led to it correctly linting another file. I think it follows the execution tree, although I haven't validated this.
I found this annoying as it can mistakenly lead you to think that linting is not working, while in fact, it's lining a file that you're not currently focussed on, especially if you have generated files that you're not interested in.
Another solution might be that you need to have the folder opened in VS Code with the go.mod file included. So you might have a folder structure that looks like workspace/application/modules/xyz.go. If you have the go.mod file in the application folder and modules is the folder you have open in VS Code it will complain.
I came across this issue by having the go extension installed, and attempting to utilize the same package name with a module under a different directory.
Files at Root: main.go, a.go, and go.mod
Sub-directory: nested/b.go
Problem: Attempting to label b.go as package main when it is under a different directory.
Solutions:
Move b.go up to project root and retain package name; all works as expected,
or
Change package name of b.go from package main to package nested, then add imports for b.go to main.go via:
// main.go
package main
import "example/nested"
func main() {
A()
nested.B()
}
and b.go:
// b.go
package nested
import "fmt"
func B() {
fmt.Println("Hello from B")
}

generate godoc documentation for an entire project?

I've been wrestling with godoc and found that "go doc" is more for providing usage help from the command line for instance:
go doc -cmd -u
lists the package comment and any functions (or other entities)
go doc *function*
then shows the documentation for an individual function (or other entity)
It seems there is a related tool called godoc.
godoc also seems to generate html on a per package and function basis.
E.g.
godoc -html hello
Generates html containing the package comment only to stdout
godoc is a really confusing name given we have go doc as well!
How can I create static documentation for the whole project?
This is similar to Godoc, create html for entire package which may have been misinterpreted as asking about documentation for packages rather than projects.
I want a build step I can use in a project that may in principle contain many packages and apps.
is there a canonical way to generate documentation for offline use even using godoc?
Go 1.12 (February 2019) is clearer on that:
godoc and go doc
In Go 1.12, godoc no longer has a command-line interface and is only a web server.
Users should use go doc for command-line help output instead.
go doc now supports the -all flag, which will cause it to print all exported APIs and their documentation, as the godoc command line used to do.
cmd/doc: add -all flag to print all documentation for package
Unlike the one for the old godoc, you need the -u flag to see unexported symbols.
This seems like the right behavior: it's consistent.
I was struggling to do this and finally, the thing that worked for me is
make sure you have "wget" installed(I am using mac, so had to install it using x-code)
log in as root user and modify the file called "robots.txt" to remove the line "Disallow : /" as this prevents wget to download the site recursively. The "robots.txt" file should be in $GOROOT path.
open a cmd and start the godocs server using the below command
godoc -http=:6060
I have my local path configured to this port.
Open another cmd and run the below command.
wget -r -np -N -E -p -k http://localhost:6060/pkg/myproject
you can mention the path of the project to have the html docs downloaded for entire project.
You can try Golds, which is an alternate Go docs generation tool (and a local docs server / code reader).
Under your project directory, you can run any of the following commands to generate HTML docs for your Go project:
golds -gen -nouses -plainsrc -wdpkgs-listing=promoted ./...
golds -gen -nouses -wdpkgs-listing=promoted ./...
golds -gen -wdpkgs-listing=promoted ./...
The first command generates the most compact docs and the last one generates the full docs, which size is 6 times of the compact docs.
BTW, I'm the author of Golds. Hope you this tool would satisfy your need.
This can be also achieved using simple wget command for that. Example: snippet
I have a similar issue with that. I'm using GitLab for my projects and I have decide to create and share with some handy GitLab CI YAML templates for Go projects that will automatically generate a static HTML Go documentation without any external packages: https://gitlab.com/tymonx/gitlab-ci
Example: Go Logger documentation
Two nice features:
Embedded Go source code files
Search box is referencing to GitLab

Set Go variable with ldflags conflicts with vendor folder

I'm currently developing a small Go app and I want to set a specific variable (like Version, GitCommit, BuildID...etc.) at build or runtime (with go build or go run) by using the -ldflags option.
Because in my company we have several projects with the same base, I decided to extract the code with these variables in a separate "info" module which could be imported in every project.
Here's my problem, say I'm running the app like this:
go run -ldflags "-X git.mycompany.com/utils/info.Version=1.0.0" app.go
This works well, and the variable is set correctly even though the variable is not part of the "main" app but in a dependency.
Then I decided to deploy the app so I used the new dep tool to generate the vendor folder.
Therefore, the "info" dependency is now in: vendor/git.mycompany.com/utils/info
Now when I run the same command as above, the said variable (Version) is not set anymore.
Am I missing something here ?
As soon as I delete the vendor folder, everything works fine again. It's like this vendor folder is conflicting with the -ldflags option or something.
Thanks in advance!
We had exactly the same problem, after lots of research we stumbled upon the solution in a comment to GitHub issue: cmd/link: -X doesn't work for vendored packages.
Solution: the full path name, relative to $GOPATH should be specified.
It works when developing git.mycompany.com/utils/info because the full path is correct.
It doesn't work for vendored dependencies because the full path from $GOPATH would be like git.mycompany.com/name-of/package/vendor/git.mycompany.com/utils/info.Version=1.0.0
Unfortunately, no documentation seem to be present about this ( for further info look at the issue ) but as Dave Cheney points out in a comment:
this is a side effect of the language way vendoring is implemented

How can I generate HTML documents for all packages inside a folder using godoc

godoc -html generates documents for only one package. However, I want to ship the project with all documents for all packages, just like when I run godoc -http. With that, I could find all packages and navigate through them from the browser.
Is it possible to generate HTML pages for all packages linked together through godoc -html?
You have two questions here:
Is it possible to generate HTML pages for all packages linked together through godoc -html?
No. Because it is not implemented into godoc (https://godoc.org/golang.org/x/tools/cmd/godoc).
The other question:
How can I generate HTML documents for all packages inside a folder
using godoc
I think the simplest way is to start godoc with the http flag: godoc -http=:6060
Then you navigate to the folder you want to get the docs. For that url you can use a webcrawler for getting the html documentation. There are already some crawler in Go (https://godoc.org/?q=crawler), if you don't want to write a crawler by your own.
I developed Golds, which is an alternate Go docs generation tool (and a local docs server / code reader). Hope you this tool would satisfy your need.
Under your project directory, you can run any of the following commands to generate HTML docs for your Go project:
golds -gen -nouses -plainsrc -wdpkgs-listing=promoted ./...
golds -gen -nouses -wdpkgs-listing=promoted ./...
golds -gen -wdpkgs-listing=promoted ./...
The first command generates the most compact docs and the last one generates the full docs, which size is 6 times of the compact docs.

Controlling what godoc documents in a repo that is not just Go packages

I have a Go sub-project in a multi-language project repo. I want to be able to use 'go get' and 'go doc'.
My layout looks like:
proton-c/bindings/go/<my packages>
examples/go/<some go examples>
I set up go-import tags on the website and created a "go" symlink in the repo root so I can go get qpid.apache.org/proton/go/<package>. It works!! It clones the entire project repo into my GOPATH but that's ok.
The problem is if I run godoc -http it does the following bad things:
ignores the root "go" symlink entirely
documents my packages as "qpid.apache.org/proton/proton-c/bindings/go/"
shows the package path to the directory with nothing in it.
The command line "godoc qpid.apache.org/proton/go/package" DOES do the right thing so godoc can extract the doc correctly but the "directory browsing" feature of godoc -http is picking up too much and not following the symlink.
So can I restrict/control what godoc picks as documentation?
I read https://github.com/golang/gddo/wiki/Source-Code-Links, but I don't think it helps my problem, could be wrong.

Resources