Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 0 additions & 21 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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
6 changes: 0 additions & 6 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
23 changes: 0 additions & 23 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 <hi@parseable.io>"
- "--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"
5 changes: 0 additions & 5 deletions Dockerfile

This file was deleted.

8 changes: 2 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -19,17 +18,14 @@ 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)
Comment on lines +21 to 22

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify whether installer scripts are pinned to immutable refs vs branch heads.
set -euo pipefail

echo "Checking for mutable raw GitHub installer refs..."
rg -n 'raw\.githubusercontent\.com/.+/(master|main)/.+\|\s*sh' Makefile .github/workflows || true

echo
echo "Checking existing golangci-lint installer invocations..."
rg -n 'golangci-lint.+install\.sh|raw\.githubusercontent\.com/golangci/golangci-lint' Makefile .github/workflows || true

Repository: parseablehq/pb

Length of output: 472


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Searching workflows for `make verifiers`..."
rg -n 'make\s+verifiers\b' .github/workflows || true

echo
echo "Searching workflows for golangci-lint-related make targets..."
rg -n 'golangci-lint|verifiers|verifier' .github/workflows/ || true

echo
echo "Locating the Makefile target(s) around lines 21-22..."
nl -ba Makefile | sed -n '1,120p'

Repository: parseablehq/pb

Length of output: 429


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Finding `verifiers` target(s) in Makefile..."
rg -n '^[[:space:]]*verifiers[[:space:]]*:' Makefile || true

echo
echo "Finding golangci-lint references in Makefile..."
rg -n 'golangci-lint' Makefile || true

echo
echo "Printing Makefile lines 1-120 for context..."
sed -n '1,120p' Makefile

echo
echo "Printing Makefile lines 1-200 around the golangci-lint installer location..."
# Try to include the installer region even if line numbers differ; grep nearby by searching for raw.githubusercontent.com golangci-lint
line=$(rg -n 'raw\.githubusercontent\.com/golangci/golangci-lint' Makefile | head -n1 | cut -d: -f1 || true)
if [ -n "${line:-}" ]; then
  start=$(( line > 40 ? line-40 : 1 ))
  end=$(( line + 40 ))
  echo "Installer match at line $line; showing Makefile:$start-$end"
  sed -n "${start},${end}p" Makefile
fi

Repository: parseablehq/pb

Length of output: 4109


🏁 Script executed:

#!/bin/bash
# Verify whether golangci-lint installer scripts are pinned to immutable refs vs branch heads.
set -euo pipefail

echo "Checking for mutable golangci-lint installer URLs..."
rg -n 'raw\.githubusercontent\.com/golangci/golangci-lint/(master|main)/install\.sh' Makefile .github/workflows || true

echo
echo "Checking for any golangci-lint install.sh executions..."
rg -n 'golangci-lint.*install\.sh|raw\.githubusercontent\.com/golangci/golangci-lint/.+/(install\.sh)' Makefile .github/workflows || true

Repository: parseablehq/pb

Length of output: 474


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Checking for mutable golangci-lint installer URLs..."
rg -n 'raw\.githubusercontent\.com/golangci/golangci-lint/(master|main)/install\.sh' Makefile .github/workflows || true

Repository: parseablehq/pb

Length of output: 264


Pin the golangci-lint installer script URL to an immutable revision.

CI runs make verifiers (which invokes getdeps) and downloads https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh, so the executed script can change independently of this repo. Pin install.sh to a specific commit SHA (or vendor it).

Suggested hardening diff
-	`@curl` -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin $(GOLANGCI_LINT_VERSION)
+	`@curl` -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/<PINNED_COMMIT_SHA>/install.sh | sh -s -- -b $(GOPATH)/bin $(GOLANGCI_LINT_VERSION)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Makefile` around lines 21 - 22, The Makefile currently downloads the
golangci-lint installer from the mutable master branch; change the curl
invocation in the Makefile (the target that runs the line "curl -sSfL
https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh
-s -- -b $(GOPATH)/bin $(GOLANGCI_LINT_VERSION)") to pin the installer URL to a
specific commit SHA (replace "master" with the commit hash in the
raw.githubusercontent URL) or, alternatively, vendor the install.sh into the
repo and point the Makefile at the vendored file; ensure the invoked symbol
remains the same (the install.sh installer used by the Makefile target) and
update any documentation/variables if you add a new VENDORED_INSTALLER path.


crosscompile:
@(env bash $(PWD)/buildscripts/cross-compile.sh)

verifiers: getdeps vet lint

docker: build
@docker build -t $(TAG) . -f Dockerfile.dev

vet:
@echo "Running $@"
@go vet $(PWD)/...
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.

<!-- TODO: Add Homebrew installation here after the tap/formula is available. -->
**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):**

Expand Down Expand Up @@ -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) -->
![pb SQL interactive TUI](docs/images/pb-sql-tui.png)

**Run SQL without the TUI:**

Expand All @@ -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) -->
![pb PromQL interactive TUI](docs/images/pb-promql-tui.png)

**Run PromQL without the TUI:**

Expand Down
4 changes: 2 additions & 2 deletions cmd/dataset.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions cmd/profile.go
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion cmd/queryList.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions cmd/role.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
4 changes: 2 additions & 2 deletions cmd/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down Expand Up @@ -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",
Expand Down
Binary file added docs/images/pb-promql-tui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/pb-sql-tui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 10 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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)
Expand Down
48 changes: 45 additions & 3 deletions scripts/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Loading