diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 638fdbd..ffe09e5 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,24 +29,3 @@ jobs: run: go build -v ./... - name: Test run: go test -v ./... - - windows-installer: - name: Test Windows installer - runs-on: windows-latest - steps: - - name: Checkout the code - uses: actions/checkout@v4 - with: - persist-credentials: false - - name: Test install.ps1 - shell: pwsh - run: | - $InstallDir = Join-Path $env:RUNNER_TEMP "pb-bin" - $env:INSTALL_DIR = $InstallDir - .\scripts\install.ps1 - - if (!(Test-Path "$InstallDir\pb.exe")) { - throw "pb.exe was not installed" - } - - & "$InstallDir\pb.exe" --help diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index c9ced15..74c9a71 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -24,12 +24,6 @@ jobs: go-version-file: go.mod cache: false - - name: Login to Docker Hub - uses: docker/login-action@v3 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - name: Run GoReleaser uses: goreleaser/goreleaser-action@v6 with: diff --git a/.goreleaser.yml b/.goreleaser.yml index 97dd9eb..a2a726c 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -34,26 +34,3 @@ archives: checksum: name_template: "pb_{{ .Version }}_checksums.txt" - -dockers: - - id: pb - goos: linux - goarch: amd64 - ids: - - pb - image_templates: - - "parseable/pb:{{ .Tag }}" - - "parseable/pb:latest" - skip_push: false - dockerfile: Dockerfile - use: docker - build_flag_templates: - - "--pull" - - "--label=org.opencontainers.image.created={{.Date}}" - - "--label=org.opencontainers.image.title=Parseable" - - "--label=maintainer=Parseable Team " - - "--label=org.opencontainers.image.vendor=Cloudnatively Pvt Ltd" - - "--label=org.opencontainers.image.licenses=AGPL-3.0" - - "--label=org.opencontainers.image.revision={{.FullCommit}}" - - "--label=org.opencontainers.image.version={{.Version}}" - - "--platform=linux/amd64" diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 65e07a1..0000000 --- a/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ubuntu:22.04 -RUN apt-get -y update && apt install -y ca-certificates -WORKDIR /app -COPY pb . -ENTRYPOINT [ "./pb" ] diff --git a/Makefile b/Makefile index 4b26e8a..d23adc7 100644 --- a/Makefile +++ b/Makefile @@ -1,8 +1,7 @@ PWD := $(shell pwd) GOPATH := $(shell go env GOPATH) -# This is just for development purposes. The version is determined at build time using git tags. +# Local builds use the nearest git tag for version metadata; fall back to "dev". VERSION ?= $(shell git describe --tags 2>/dev/null || echo "dev") -TAG ?= "parseablehq/pb:$(VERSION)" LDFLAGS := $(shell go run buildscripts/gen-ldflags.go $(VERSION)) GOARCH := $(shell go env GOARCH) @@ -19,7 +18,7 @@ checks: getdeps: @mkdir -p ${GOPATH}/bin @echo "Installing golangci-lint $(GOLANGCI_LINT_VERSION)" -# Will need to make it more error prone in future! +# TODO: Make dependency installation more robust and reproducible. @curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin $(GOLANGCI_LINT_VERSION) crosscompile: @@ -27,9 +26,6 @@ crosscompile: verifiers: getdeps vet lint -docker: build - @docker build -t $(TAG) . -f Dockerfile.dev - vet: @echo "Running $@" @go vet $(PWD)/... diff --git a/README.md b/README.md index 47c4f19..9e746ee 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,13 @@ Downloads the latest release, verifies the SHA-256 checksum, installs to `%USERPROFILE%\bin`, and adds that folder to your user `PATH`. Open a new PowerShell window after installation. - +**Homebrew (macOS and Linux):** + +```bash +brew install parseablehq/tap/pb +``` + +> Use the full tap name above. `brew install pb` installs an unrelated Homebrew cask. **Pre-built binary (Linux/macOS/Windows):** @@ -165,7 +171,7 @@ Start with a pre-filled query: ```sh pb sql run "SELECT * FROM backend-shop WHERE order.amount > 999 LIMIT 5" --from=1h -i ``` - +![pb SQL interactive TUI](docs/images/pb-sql-tui.png) **Run SQL without the TUI:** @@ -185,7 +191,7 @@ Start with a pre-filled query: pb promql run "process.cpu.time{process.cpu.state!=""}" --dataset astronomy-shop-metrics --from=1h -i ``` - +![pb PromQL interactive TUI](docs/images/pb-promql-tui.png) **Run PromQL without the TUI:** diff --git a/cmd/dataset.go b/cmd/dataset.go index f8c9cf7..dccfe1c 100644 --- a/cmd/dataset.go +++ b/cmd/dataset.go @@ -465,7 +465,7 @@ func init() { } var RemoveDatasetCmd = &cobra.Command{ - Use: "remove|rm dataset-name", + Use: "remove dataset-name", Aliases: []string{"rm"}, Example: " pb dataset remove backend_logs\n pb dataset remove backend_logs --type logs", Short: "Delete a dataset", @@ -552,7 +552,7 @@ func init() { // ListDatasetCmd is the list command for datasets var ListDatasetCmd = &cobra.Command{ - Use: "list|ls", + Use: "list", Aliases: []string{"ls"}, Example: " pb dataset list", Short: "List all datasets", diff --git a/cmd/profile.go b/cmd/profile.go index 01fb161..008f92b 100644 --- a/cmd/profile.go +++ b/cmd/profile.go @@ -154,7 +154,7 @@ var AddProfileCmd = &cobra.Command{ } var RemoveProfileCmd = &cobra.Command{ - Use: "remove|rm profile-name", + Use: "remove profile-name", Aliases: []string{"rm"}, Example: " pb profile remove local_parseable", Args: cobra.ExactArgs(1), @@ -328,7 +328,7 @@ var UpdateProfileCmd = &cobra.Command{ } var ListProfileCmd = &cobra.Command{ - Use: "list|ls profiles", + Use: "list profiles", Aliases: []string{"ls"}, Short: "List all added profiles", Example: " pb profile list", diff --git a/cmd/queryList.go b/cmd/queryList.go index 89d5a6b..3938462 100644 --- a/cmd/queryList.go +++ b/cmd/queryList.go @@ -30,7 +30,7 @@ import ( ) var SavedQueryList = &cobra.Command{ - Use: "list|ls", + Use: "list", Aliases: []string{"ls"}, Example: "pb sql list [-o | --output]", Short: "List of saved queries", diff --git a/cmd/role.go b/cmd/role.go index e4e2fb3..1528612 100644 --- a/cmd/role.go +++ b/cmd/role.go @@ -143,7 +143,7 @@ var AddRoleCmd = &cobra.Command{ } var RemoveRoleCmd = &cobra.Command{ - Use: "remove|rm role-name", + Use: "remove role-name", Aliases: []string{"rm"}, Example: " pb role remove ingestor", Short: "Delete a role", @@ -188,7 +188,7 @@ var RemoveRoleCmd = &cobra.Command{ } var ListRoleCmd = &cobra.Command{ - Use: "list|ls", + Use: "list", Aliases: []string{"ls"}, Short: "List all roles", Example: " pb role list", diff --git a/cmd/user.go b/cmd/user.go index 849a77b..6da5900 100644 --- a/cmd/user.go +++ b/cmd/user.go @@ -149,7 +149,7 @@ var AddUserCmd = func() *cobra.Command { }() var RemoveUserCmd = &cobra.Command{ - Use: "remove|rm user-name", + Use: "remove user-name", Aliases: []string{"rm"}, Example: " pb user remove bob", Short: "Delete a user", @@ -275,7 +275,7 @@ var SetUserRoleCmd = &cobra.Command{ } var ListUserCmd = &cobra.Command{ - Use: "list|ls", + Use: "list", Aliases: []string{"ls"}, Short: "List all users", Example: " pb user list", diff --git a/docs/images/pb-promql-tui.png b/docs/images/pb-promql-tui.png new file mode 100644 index 0000000..c83c754 Binary files /dev/null and b/docs/images/pb-promql-tui.png differ diff --git a/docs/images/pb-sql-tui.png b/docs/images/pb-sql-tui.png new file mode 100644 index 0000000..55a89ab Binary files /dev/null and b/docs/images/pb-sql-tui.png differ diff --git a/main.go b/main.go index 9926df5..3764269 100644 --- a/main.go +++ b/main.go @@ -387,7 +387,7 @@ func renderCommandHelp(cmd *cobra.Command) { if !child.IsAvailableCommand() && child.Name() != "help" { continue } - fmt.Fprintf(out, " %-12s %s\n", child.Name(), child.Short) + fmt.Fprintf(out, " %-16s %s\n", commandDisplayName(child), child.Short) } fmt.Fprintln(out) } @@ -415,6 +415,15 @@ func renderCommandHelp(cmd *cobra.Command) { } } +func commandDisplayName(cmd *cobra.Command) string { + name := cmd.Name() + aliases := cmd.Aliases + if len(aliases) == 0 { + return name + } + return name + "|" + strings.Join(aliases, "|") +} + // Wrapper to combine existing pre-run logic and ULID check func combinedPreRun(cmd *cobra.Command, args []string) error { err := pb.PreRunDefaultProfile(cmd, args) diff --git a/scripts/install.sh b/scripts/install.sh index 64c64c7..bdf48fe 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -40,6 +40,47 @@ checksum() { fi } +detect_user_shell() { + if [ -n "${SHELL:-}" ]; then + printf '%s\n' "${SHELL##*/}" + else + printf '%s\n' "sh" + fi +} + +print_path_instructions() { + install_dir="$1" + shell_name="$(detect_user_shell)" + + echo "" + case "$shell_name" in + bash) + echo "$install_dir is not in your PATH. Add it with:" + echo "" + echo " echo 'export PATH=\"$install_dir:\$PATH\"' >> ~/.bashrc" + echo " . ~/.bashrc" + ;; + zsh) + echo "$install_dir is not in your PATH. Add it with:" + echo "" + echo " echo 'export PATH=\"$install_dir:\$PATH\"' >> ~/.zshrc" + echo " source ~/.zshrc" + ;; + fish) + echo "$install_dir is not in your PATH. Add it with:" + echo "" + echo " mkdir -p ~/.config/fish" + echo " echo 'fish_add_path $install_dir' >> ~/.config/fish/config.fish" + echo " source ~/.config/fish/config.fish" + ;; + *) + echo "$install_dir is not in your PATH. Add it to your shell startup file:" + echo "" + echo " export PATH=\"$install_dir:\$PATH\"" + ;; + esac +} + install_binary() { src="$1" dst="$2" @@ -120,6 +161,7 @@ chmod +x "$tmpdir/$BINARY_NAME" install_binary "$tmpdir/$BINARY_NAME" "$INSTALL_DIR/$BINARY_NAME" echo "$BINARY_NAME installed to $INSTALL_DIR/$BINARY_NAME" -if ! command -v "$BINARY_NAME" >/dev/null 2>&1; then - echo "Add $INSTALL_DIR to your PATH to run '$BINARY_NAME' from any directory." -fi +case ":$PATH:" in +*":$INSTALL_DIR:"*) ;; +*) print_path_instructions "$INSTALL_DIR" ;; +esac