diff --git a/cmd/aspect/docs/BUILD.bazel b/cmd/aspect/docs/BUILD.bazel new file mode 100644 index 000000000..4fb7e400b --- /dev/null +++ b/cmd/aspect/docs/BUILD.bazel @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "docs", + srcs = ["docs.go"], + importpath = "aspect.build/cli/cmd/aspect/docs", + visibility = ["//visibility:public"], + deps = [ + "//pkg/aspect/docs", + "//pkg/ioutils", + "@com_github_spf13_cobra//:cobra", + ], +) diff --git a/cmd/aspect/docs/docs.go b/cmd/aspect/docs/docs.go new file mode 100644 index 000000000..91612ca4b --- /dev/null +++ b/cmd/aspect/docs/docs.go @@ -0,0 +1,33 @@ +/* +Copyright © 2021 Aspect Build Systems + +Not licensed for re-use +*/ + +package docs + +import ( + "github.com/spf13/cobra" + + "aspect.build/cli/pkg/aspect/docs" + "aspect.build/cli/pkg/ioutils" +) + +func NewDefaultDocsCmd() *cobra.Command { + return NewDocsCmd(ioutils.DefaultStreams) +} + +func NewDocsCmd(streams ioutils.Streams) *cobra.Command { + v := docs.New(streams) + + cmd := &cobra.Command{ + Use: "docs", + Short: "Open documentation in the browser", + Long: `Given a selected topic, open the relevant API docs in a browser window. + The mechanism of choosing the browser to open is documented at https://github.com/pkg/browser + By default, opens docs.bazel.build`, + RunE: v.Run, + } + + return cmd +} diff --git a/cmd/aspect/root/BUILD.bazel b/cmd/aspect/root/BUILD.bazel index 762e55dfd..683cf6fbc 100644 --- a/cmd/aspect/root/BUILD.bazel +++ b/cmd/aspect/root/BUILD.bazel @@ -6,6 +6,7 @@ go_library( importpath = "aspect.build/cli/cmd/aspect/root", visibility = ["//visibility:public"], deps = [ + "//cmd/aspect/docs", "//cmd/aspect/version", "//docs/help/topics", "//pkg/ioutils", diff --git a/cmd/aspect/root/root.go b/cmd/aspect/root/root.go index 1f90641b7..c621794ae 100644 --- a/cmd/aspect/root/root.go +++ b/cmd/aspect/root/root.go @@ -15,6 +15,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "aspect.build/cli/cmd/aspect/docs" "aspect.build/cli/cmd/aspect/version" "aspect.build/cli/docs/help/topics" "aspect.build/cli/pkg/ioutils" @@ -64,6 +65,7 @@ func NewRootCmd(streams ioutils.Streams, defaultInteractive bool) *cobra.Command // ### Child commands // IMPORTANT: when adding a new command, also update the _DOCS list in /docs/BUILD.bazel cmd.AddCommand(version.NewDefaultVersionCmd()) + cmd.AddCommand(docs.NewDefaultDocsCmd()) // ### "Additional help topic commands" which are not runnable // https://pkg.go.dev/github.com/spf13/cobra#Command.IsAdditionalHelpTopicCommand diff --git a/docs/BUILD.bazel b/docs/BUILD.bazel index 8454806da..d4cbfd497 100644 --- a/docs/BUILD.bazel +++ b/docs/BUILD.bazel @@ -4,6 +4,7 @@ load("@bazel_skylib//rules:write_file.bzl", "write_file") # This list must be updated when we add a new command _DOCS = [ "aspect.md", + "aspect_docs.md", "aspect_version.md", ] diff --git a/docs/aspect.md b/docs/aspect.md index 8043d6741..c305917b5 100644 --- a/docs/aspect.md +++ b/docs/aspect.md @@ -16,6 +16,7 @@ Aspect CLI is a better frontend for running bazel ### SEE ALSO +* [aspect docs](aspect_docs.md) - Open documentation in the browser * [aspect version](aspect_version.md) - Print the version of aspect CLI as well as tools it invokes ###### Auto generated by spf13/cobra diff --git a/docs/aspect_docs.md b/docs/aspect_docs.md new file mode 100644 index 000000000..8533a3ea1 --- /dev/null +++ b/docs/aspect_docs.md @@ -0,0 +1,32 @@ +## aspect docs + +Open documentation in the browser + +### Synopsis + +Given a selected topic, open the relevant API docs in a browser window. + The mechanism of choosing the browser to open is documented at https://github.com/pkg/browser + By default, opens docs.bazel.build + +``` +aspect docs [flags] +``` + +### Options + +``` + -h, --help help for docs +``` + +### Options inherited from parent commands + +``` + --config string config file (default is $HOME/.aspect.yaml) + --interactive Interactive mode (e.g. prompts for user input) +``` + +### SEE ALSO + +* [aspect](aspect.md) - Aspect.build bazel wrapper + +###### Auto generated by spf13/cobra diff --git a/go.bzl b/go.bzl index 7dcb515ae..728a58f01 100644 --- a/go.bzl +++ b/go.bzl @@ -623,6 +623,13 @@ def deps(): sum = "h1:7NiByeVF4jKSG1lDF3X8LTIkq2/bu+1uYbIm1eS5tzk=", version = "v1.9.2", ) + go_repository( + name = "com_github_pkg_browser", + importpath = "github.com/pkg/browser", + sum = "h1:TdFv+3Gr3GaghJ/o80aulO4ian7GHGWMdLBXoLZH1Is=", + version = "v0.0.0-20210904010418-6d279e18f982", + ) + go_repository( name = "com_github_pkg_errors", importpath = "github.com/pkg/errors", @@ -1010,8 +1017,8 @@ def deps(): go_repository( name = "org_golang_x_sys", importpath = "golang.org/x/sys", - sum = "h1:faDu4veV+8pcThn4fewv6TVlNCezafGoC1gM/mxQLbQ=", - version = "v0.0.0-20210611083646-a4fc73990273", + sum = "h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk=", + version = "v0.0.0-20210616045830-e2b7044e8c71", ) go_repository( name = "org_golang_x_term", @@ -1033,10 +1040,10 @@ def deps(): ) go_repository( name = "org_golang_x_tools", + build_directives = ["gazelle:exclude **/testdata/**/*"], importpath = "golang.org/x/tools", sum = "h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=", version = "v0.0.0-20201224043029-2b0845dc783e", - build_directives = ["gazelle:exclude **/testdata/**/*"], ) go_repository( name = "org_golang_x_xerrors", diff --git a/go.mod b/go.mod index b32cf0c85..96ca1e4f2 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.16 require ( github.com/bazelbuild/bazelisk v1.10.1 + github.com/bazelbuild/rules_go v0.28.0 github.com/fatih/color v1.12.0 github.com/magiconair/properties v1.8.5 // indirect github.com/mattn/go-isatty v0.0.13 @@ -11,11 +12,11 @@ require ( github.com/mitchellh/mapstructure v1.4.1 // indirect github.com/onsi/gomega v1.16.0 github.com/pelletier/go-toml v1.9.2 // indirect + github.com/pkg/browser v0.0.0-20210904010418-6d279e18f982 github.com/spf13/afero v1.6.0 // indirect github.com/spf13/cast v1.3.1 // indirect github.com/spf13/cobra v1.1.3 github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/viper v1.7.1 - golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 // indirect gopkg.in/ini.v1 v1.62.0 // indirect ) diff --git a/go.sum b/go.sum index b962aeef2..4db7f4a8d 100644 --- a/go.sum +++ b/go.sum @@ -262,6 +262,8 @@ github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FI github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.2 h1:7NiByeVF4jKSG1lDF3X8LTIkq2/bu+1uYbIm1eS5tzk= github.com/pelletier/go-toml v1.9.2/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pkg/browser v0.0.0-20210904010418-6d279e18f982 h1:TdFv+3Gr3GaghJ/o80aulO4ian7GHGWMdLBXoLZH1Is= +github.com/pkg/browser v0.0.0-20210904010418-6d279e18f982/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -438,8 +440,8 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 h1:faDu4veV+8pcThn4fewv6TVlNCezafGoC1gM/mxQLbQ= -golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71 h1:X/2sJAybVknnUnV7AD2HdT6rm2p5BP6eH2j+igduWgk= +golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/pkg/aspect/docs/BUILD.bazel b/pkg/aspect/docs/BUILD.bazel new file mode 100644 index 000000000..61a570135 --- /dev/null +++ b/pkg/aspect/docs/BUILD.bazel @@ -0,0 +1,13 @@ +load("@io_bazel_rules_go//go:def.bzl", "go_library") + +go_library( + name = "docs", + srcs = ["docs.go"], + importpath = "aspect.build/cli/pkg/aspect/docs", + visibility = ["//visibility:public"], + deps = [ + "//pkg/ioutils", + "@com_github_pkg_browser//:browser", + "@com_github_spf13_cobra//:cobra", + ], +) diff --git a/pkg/aspect/docs/docs.go b/pkg/aspect/docs/docs.go new file mode 100644 index 000000000..a35fec017 --- /dev/null +++ b/pkg/aspect/docs/docs.go @@ -0,0 +1,49 @@ +/* +Copyright © 2021 Aspect Build Systems Inc + +Not licensed for re-use. +*/ + +package docs + +import ( + "fmt" + "os" + "strings" + + "aspect.build/cli/pkg/ioutils" + "github.com/pkg/browser" + "github.com/spf13/cobra" +) + +type Docs struct { + ioutils.Streams +} + +func New(streams ioutils.Streams) *Docs { + return &Docs{ + Streams: streams, + } +} + +func (v *Docs) Run(_ *cobra.Command, args []string) error { + // TODO: we should open the browser to the bazel version matching what is running + dest := "https://docs.bazel.build" + + // Detect requests for docs on rules, which we host + if len(args) == 1 { + if strings.HasPrefix(args[0], "rules_") { + dest = fmt.Sprintf("https://docs.aspect.dev/%s", args[0]) + } else { + dest = fmt.Sprintf("https://docs.bazel.build/versions/main/%s.html", args[0]) + } + } + // TODO: a way to lookup whatever the user typed after "docs" using docs.aspect.dev search + // as far as I can tell, Algolia doesn't provide a way to render results on a dedicated search page + // so I can't find a way to hyperlink to a search result. + if err := browser.OpenURL(dest); err != nil { + fmt.Fprintf(os.Stderr, "Failed to open link in the browser: %v\n", err) + } + + return nil +}