From 7b072eac0d892a77dc6d9e7b86fe3852e8c271c6 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 21 Jan 2026 15:02:44 -0500 Subject: [PATCH 01/21] feat: notify user their version of dbc is out of date --- cmd/dbc/main.go | 9 +++++++++ drivers.go | 14 ++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/cmd/dbc/main.go b/cmd/dbc/main.go index f6f4bccb..c5ea2d4e 100644 --- a/cmd/dbc/main.go +++ b/cmd/dbc/main.go @@ -23,6 +23,7 @@ import ( tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" + "github.com/Masterminds/semver/v3" "github.com/alexflint/go-arg" "github.com/columnar-tech/dbc" "github.com/columnar-tech/dbc/auth" @@ -291,6 +292,14 @@ func main() { } } + latestVer, err := dbc.GetLatestDbcVersion() + if !args.Quiet && dbc.Version != "(devel)" && err == nil { + if semver.MustParse(dbc.Version).LessThan(latestVer) { + fmt.Printf(descStyle.Render("dbc Version %s is available! You are using %s, please upgrade.\n\n"), + latestVer, dbc.Version) + } + } + if m, err = prog.Run(); err != nil { fmt.Fprintln(os.Stderr, "Error running program:", err) os.Exit(1) diff --git a/drivers.go b/drivers.go index 231e0550..44ca0bac 100644 --- a/drivers.go +++ b/drivers.go @@ -527,3 +527,17 @@ func SignedByColumnar(lib, sig io.Reader) error { return result.SignatureError() } + +func GetLatestDbcVersion() (*semver.Version, error) { + resp, err := makereq("https://dbc.columnar.tech") + if err != nil { + return nil, fmt.Errorf("failed to fetch latest dbc version: %w", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusNoContent { + return nil, fmt.Errorf("failed to fetch latest dbc version: %s", resp.Status) + } + + return semver.NewVersion(resp.Header.Get("x-dbc-latest")) +} From 2fa56331c1f0d076d9e6f3746d7b8ccaafa13015 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 21 Jan 2026 18:21:59 -0500 Subject: [PATCH 02/21] Update cmd/dbc/main.go Co-authored-by: Ian Cook --- cmd/dbc/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/dbc/main.go b/cmd/dbc/main.go index c5ea2d4e..556e0511 100644 --- a/cmd/dbc/main.go +++ b/cmd/dbc/main.go @@ -295,7 +295,7 @@ func main() { latestVer, err := dbc.GetLatestDbcVersion() if !args.Quiet && dbc.Version != "(devel)" && err == nil { if semver.MustParse(dbc.Version).LessThan(latestVer) { - fmt.Printf(descStyle.Render("dbc Version %s is available! You are using %s, please upgrade.\n\n"), + fmt.Printf(descStyle.Render("dbc version %s is available! You are using version %s. Please upgrade.\n\n"), latestVer, dbc.Version) } } From 5c767fa845239e81704fa315df81f2b75b1b79ff Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 4 Feb 2026 13:58:29 -0500 Subject: [PATCH 03/21] add build tag --- cmd/dbc/latest.go | 34 ++++++++++++++++++++++++++++++++++ cmd/dbc/latest_ignore.go | 19 +++++++++++++++++++ cmd/dbc/main.go | 9 ++------- 3 files changed, 55 insertions(+), 7 deletions(-) create mode 100644 cmd/dbc/latest.go create mode 100644 cmd/dbc/latest_ignore.go diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go new file mode 100644 index 00000000..11f4d63c --- /dev/null +++ b/cmd/dbc/latest.go @@ -0,0 +1,34 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build !no_notify_latest + +package main + +import ( + "fmt" + + "github.com/Masterminds/semver/v3" + "github.com/columnar-tech/dbc" +) + +func notifyLatest() { + latestVer, err := dbc.GetLatestDbcVersion() + if dbc.Version != "(devel)" && err == nil { + if semver.MustParse(dbc.Version).LessThan(latestVer) { + fmt.Printf(descStyle.Render("dbc version %s is available! You are using version %s. Please upgrade.\n\n"), + latestVer, dbc.Version) + } + } +} diff --git a/cmd/dbc/latest_ignore.go b/cmd/dbc/latest_ignore.go new file mode 100644 index 00000000..7f1c63b3 --- /dev/null +++ b/cmd/dbc/latest_ignore.go @@ -0,0 +1,19 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build no_notify_latest + +package main + +func notifyLatest() {} diff --git a/cmd/dbc/main.go b/cmd/dbc/main.go index 556e0511..f7f4690c 100644 --- a/cmd/dbc/main.go +++ b/cmd/dbc/main.go @@ -23,7 +23,6 @@ import ( tea "charm.land/bubbletea/v2" "charm.land/lipgloss/v2" - "github.com/Masterminds/semver/v3" "github.com/alexflint/go-arg" "github.com/columnar-tech/dbc" "github.com/columnar-tech/dbc/auth" @@ -292,12 +291,8 @@ func main() { } } - latestVer, err := dbc.GetLatestDbcVersion() - if !args.Quiet && dbc.Version != "(devel)" && err == nil { - if semver.MustParse(dbc.Version).LessThan(latestVer) { - fmt.Printf(descStyle.Render("dbc version %s is available! You are using version %s. Please upgrade.\n\n"), - latestVer, dbc.Version) - } + if !args.Quiet { + notifyLatest() } if m, err = prog.Run(); err != nil { From b93b9543124eb9f0061ff659ece3ad6d3652267b Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Mon, 20 Apr 2026 12:20:36 -0400 Subject: [PATCH 04/21] updates from feedback --- cmd/dbc/latest.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index 11f4d63c..35cfc38f 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -17,18 +17,26 @@ package main import ( + "errors" "fmt" + "os" + "path/filepath" "github.com/Masterminds/semver/v3" "github.com/columnar-tech/dbc" + "github.com/columnar-tech/dbc/config" ) func notifyLatest() { - latestVer, err := dbc.GetLatestDbcVersion() - if dbc.Version != "(devel)" && err == nil { - if semver.MustParse(dbc.Version).LessThan(latestVer) { - fmt.Printf(descStyle.Render("dbc version %s is available! You are using version %s. Please upgrade.\n\n"), - latestVer, dbc.Version) + // skip notifying if $dbc_config_home/.no-update exists + _, err := os.Stat(filepath.Join(config.ConfigUser.ConfigLocation(), ".no-update")) + if errors.Is(err, os.ErrNotExist) { + latestVer, err := dbc.GetLatestDbcVersion() + if dbc.Version != "(devel)" && err == nil { + if semver.MustParse(dbc.Version).LessThan(latestVer) { + fmt.Printf(descStyle.Render("Update available: A new version of dbc is available. You're running %s and %s is available. Please upgrade.\nChangelog: %s. Docs: %s\n\n"), + dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") + } } } } From 50273ffaabdee96d45ae17caa0c60a820ac237f0 Mon Sep 17 00:00:00 2001 From: Bryce Mecum Date: Mon, 20 Apr 2026 19:56:38 -0700 Subject: [PATCH 05/21] Add docs for update notifications --- docs/getting_started/installation.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index 97cd0e09..ec1eccec 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -211,6 +211,21 @@ dbc can generate shell completions for a number of common shells. You can use the `dbc completion` subcommand to print extended instructions for your shell, including how to enable your shell's completion mechanism. For example, to print setup instructions for Bash, run `dbc completion bash --help`. +## Updating + +If you installed dbc using the [Standalone Installer](#standalone-installer) or manually through [GitHub Releases](#github-releases), dbc will automatically notify you if your version is out of date and will provide instructions for updating. + +For other installation methods, dbc won't automatically notify of updates and you should upgrade dbc in whatever way is standard for your installation method. + +!!! note + To silence update notifications, create an empty file called `.no-update` in the dbc configuration directory for your operating system: + + - Linux: `~/.config/columnar/dbc/.no-update` + - macOS: `~/Library/Application Support/Columnar/dbc/.no-update` + - Windows: `%AppData%/Columnar/dbc/.no-update` + + If you use a custom `$XDG_CONFIG_HOME`, use `$XDG_CONFIG_HOME/columnar/dbc/.no-update`. + ## Uninstallation To remove dbc from your system, run the uninstall command corresponding to your installation method. From 152bee8f7ade5a729efdb618543552272a3cae6e Mon Sep 17 00:00:00 2001 From: Bryce Mecum Date: Mon, 20 Apr 2026 19:58:26 -0700 Subject: [PATCH 06/21] Update installation.md --- docs/getting_started/installation.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/getting_started/installation.md b/docs/getting_started/installation.md index ec1eccec..3ce6e38f 100644 --- a/docs/getting_started/installation.md +++ b/docs/getting_started/installation.md @@ -213,6 +213,8 @@ dbc can generate shell completions for a number of common shells. ## Updating +{{ since_version('v0.2.0') }} + If you installed dbc using the [Standalone Installer](#standalone-installer) or manually through [GitHub Releases](#github-releases), dbc will automatically notify you if your version is out of date and will provide instructions for updating. For other installation methods, dbc won't automatically notify of updates and you should upgrade dbc in whatever way is standard for your installation method. From a12e7a09fa1b9813a243e834cc73f7e4a41fc812 Mon Sep 17 00:00:00 2001 From: Bryce Mecum Date: Mon, 20 Apr 2026 20:39:52 -0700 Subject: [PATCH 07/21] Set up notify/no-notify in goreleaser --- .goreleaser.yaml | 36 ++++++++++++++++++++++++++++++++---- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 69747a62..3812f98e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -34,7 +34,10 @@ git: tag_sort: smartsemver builds: - - main: ./cmd/dbc + # Set up separate builds for no_notify_latest/!no_notify-latest + - &build-defaults + id: yes-notify-build + main: ./cmd/dbc binary: dbc ldflags: - -s -w @@ -52,13 +55,24 @@ builds: goarch: arm64 mod_timestamp: "{{ .CommitTimestamp }}" hooks: - post: # sign the windows binaries + post: - if: '{{ and (eq .Os "windows") (isEnvSet "SM_API_KEY") }}' cmd: >- smctl sign --keypair-alias "{{ .Env.SM_KEYPAIR_ALIAS }}" --input "{{ .Path }}" --config-file "{{ .Env.PKCS11_CONFIG }}" + - <<: *build-defaults + id: no-notify-build + flags: + - -tags=no_notify_latest + archives: - - id: archives + # Homebrew uses archives not builds so we set up separate archives too + # &archive-defaults anchored on the simpler entry (no hooks). + # Used for GitHub releases, blobs, and signs. + - &archive-defaults + id: archives + builds: + - yes-notify-build formats: [tar.gz] # this name template makes the OS and Arch compatible with the results of `uname`. name_template: >- @@ -78,6 +92,13 @@ archives: format_overrides: - goos: windows formats: [zip] + + # Silent archives (no-notify build) — used for Homebrew casks and Python wheels. + # Wheels are redistributable packages and should not notify for updates. + - <<: *archive-defaults + id: no-notify-archives + builds: + - no-notify-build hooks: after: # build wheels for each platform we built for @@ -131,6 +152,7 @@ dockers: - image_templates: - "columnar/dbc:{{ .Version }}-amd64" use: buildx + ids: [no-notify-build] dockerfile: Dockerfile skip_push: false build_flag_templates: @@ -141,6 +163,7 @@ dockers: - "columnar/dbc:v{{ .Major }}.{{ .Minor }}-amd64" - "columnar/dbc:latest-amd64" use: buildx + ids: [no-notify-build] dockerfile: Dockerfile skip_push: auto build_flag_templates: @@ -148,6 +171,7 @@ dockers: - image_templates: - "columnar/dbc:{{ .Version }}-arm64v8" use: buildx + ids: [no-notify-build] goarch: arm64 dockerfile: Dockerfile skip_push: false @@ -159,6 +183,7 @@ dockers: - "columnar/dbc:v{{ .Major }}.{{ .Minor }}-arm64v8" - "columnar/dbc:latest-arm64v8" use: buildx + ids: [no-notify-build] goarch: arm64 dockerfile: Dockerfile skip_push: auto @@ -208,6 +233,7 @@ docker_manifests: nfpms: - id: pkgs + builds: [no-notify-build] package_name: dbc file_name_template: "{{ .ConventionalFileName }}" if: '{{ eq .Os "linux" }}' @@ -236,6 +262,7 @@ nfpms: snapcrafts: - id: snaps + builds: [no-notify-build] name: dbc summary: The command line tool for installing and managing ADBC drivers description: The command line tool for installing and managing ADBC drivers @@ -260,6 +287,7 @@ snapcrafts: msi: - id: msi + ids: [no-notify-build] name: "dbc-{{ .Version }}-{{ .MsiArch }}" wxs: ./resources/dbc.wxs extensions: @@ -312,7 +340,7 @@ homebrew_casks: - dbc@{{ .Version }} - dbc@{{ .Major }}.{{ .Minor }} ids: - - archives + - no-notify-archives url: template: "https://github.com/columnar-tech/dbc/releases/download/{{ .Tag }}/{{ .ArtifactName }}" verified: "github.com/columnar-tech/dbc/" From 4ec8beaa4e00820fc059f6171c01fbee7279b331 Mon Sep 17 00:00:00 2001 From: Bryce Mecum Date: Mon, 20 Apr 2026 20:43:51 -0700 Subject: [PATCH 08/21] builds -> ids --- .goreleaser.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 3812f98e..15ddde56 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -71,7 +71,7 @@ archives: # Used for GitHub releases, blobs, and signs. - &archive-defaults id: archives - builds: + ids: - yes-notify-build formats: [tar.gz] # this name template makes the OS and Arch compatible with the results of `uname`. @@ -97,7 +97,7 @@ archives: # Wheels are redistributable packages and should not notify for updates. - <<: *archive-defaults id: no-notify-archives - builds: + ids: - no-notify-build hooks: after: @@ -233,7 +233,7 @@ docker_manifests: nfpms: - id: pkgs - builds: [no-notify-build] + ids: [no-notify-build] package_name: dbc file_name_template: "{{ .ConventionalFileName }}" if: '{{ eq .Os "linux" }}' @@ -262,7 +262,7 @@ nfpms: snapcrafts: - id: snaps - builds: [no-notify-build] + ids: [no-notify-build] name: dbc summary: The command line tool for installing and managing ADBC drivers description: The command line tool for installing and managing ADBC drivers From a007b82046b62e4bf712002b54cb6c6ab4494cbe Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 11:23:05 -0400 Subject: [PATCH 09/21] fix formatting, config path --- cmd/dbc/latest.go | 14 ++++++++++---- internal/paths.go | 15 ++++++++++++--- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index 35cfc38f..b9cea803 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -18,24 +18,30 @@ package main import ( "errors" - "fmt" "os" "path/filepath" + "charm.land/lipgloss/v2" "github.com/Masterminds/semver/v3" "github.com/columnar-tech/dbc" - "github.com/columnar-tech/dbc/config" + "github.com/columnar-tech/dbc/internal" ) func notifyLatest() { + configDir, err := internal.GetDbcConfigPath() + if err != nil { + return + } + // skip notifying if $dbc_config_home/.no-update exists - _, err := os.Stat(filepath.Join(config.ConfigUser.ConfigLocation(), ".no-update")) + _, err = os.Stat(filepath.Join(configDir, ".no-update")) if errors.Is(err, os.ErrNotExist) { latestVer, err := dbc.GetLatestDbcVersion() if dbc.Version != "(devel)" && err == nil { if semver.MustParse(dbc.Version).LessThan(latestVer) { - fmt.Printf(descStyle.Render("Update available: A new version of dbc is available. You're running %s and %s is available. Please upgrade.\nChangelog: %s. Docs: %s\n\n"), + lipgloss.Printf(descStyle.Render("Update available: A new version of dbc is available. You're running %s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") + lipgloss.Println() } } } diff --git a/internal/paths.go b/internal/paths.go index 71bc908b..27b967cb 100644 --- a/internal/paths.go +++ b/internal/paths.go @@ -41,9 +41,7 @@ func GetUserConfigPath() (string, error) { return finalDir, nil } -// Directory for dbc credentials. This dir is distinct from GetUserConfigPath -// except for on macOS where it's the same -func GetCredentialPath() (string, error) { +func GetDbcConfigPath() (string, error) { dir := os.Getenv("XDG_DATA_HOME") if dir == "" { switch runtime.GOOS { @@ -70,5 +68,16 @@ func GetCredentialPath() (string, error) { return "", errors.New("path in $XDG_DATA_HOME is relative") } + return dir, nil +} + +// Directory for dbc credentials. This dir is distinct from GetUserConfigPath +// except for on macOS where it's the same +func GetCredentialPath() (string, error) { + dir, err := GetDbcConfigPath() + if err != nil { + return "", fmt.Errorf("failed to get dbc config path: %w", err) + } + return filepath.Join(dir, "dbc", "credentials", "credentials.toml"), nil } From c367112e75bec3a313baa44a9f3475cdd7e14269 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 12:31:56 -0400 Subject: [PATCH 10/21] don't use build tags, use exe path --- .goreleaser.yaml | 54 ++++++++++------------------------------ cmd/dbc/latest.go | 51 +++++++++++++++++++++++++++++++++++-- cmd/dbc/latest_ignore.go | 19 -------------- 3 files changed, 62 insertions(+), 62 deletions(-) delete mode 100644 cmd/dbc/latest_ignore.go diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 15ddde56..1b50596e 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -33,11 +33,8 @@ metadata: git: tag_sort: smartsemver -builds: - # Set up separate builds for no_notify_latest/!no_notify-latest - - &build-defaults - id: yes-notify-build - main: ./cmd/dbc +builds: + - main: ./cmd/dbc binary: dbc ldflags: - -s -w @@ -58,21 +55,10 @@ builds: post: - if: '{{ and (eq .Os "windows") (isEnvSet "SM_API_KEY") }}' cmd: >- - smctl sign --keypair-alias "{{ .Env.SM_KEYPAIR_ALIAS }}" --input "{{ .Path }}" --config-file "{{ .Env.PKCS11_CONFIG }}" - - - <<: *build-defaults - id: no-notify-build - flags: - - -tags=no_notify_latest - -archives: - # Homebrew uses archives not builds so we set up separate archives too - # &archive-defaults anchored on the simpler entry (no hooks). - # Used for GitHub releases, blobs, and signs. - - &archive-defaults - id: archives - ids: - - yes-notify-build + smctl sign --keypair-alias "{{ .Env.SM_KEYPAIR_ALIAS }}" --input "{{ .Path }}" --config-file "{{ .Env.PKCS11_CONFIG }}" + +archives: + - id: archives formats: [tar.gz] # this name template makes the OS and Arch compatible with the results of `uname`. name_template: >- @@ -92,13 +78,6 @@ archives: format_overrides: - goos: windows formats: [zip] - - # Silent archives (no-notify build) — used for Homebrew casks and Python wheels. - # Wheels are redistributable packages and should not notify for updates. - - <<: *archive-defaults - id: no-notify-archives - ids: - - no-notify-build hooks: after: # build wheels for each platform we built for @@ -151,8 +130,7 @@ changelog: dockers: - image_templates: - "columnar/dbc:{{ .Version }}-amd64" - use: buildx - ids: [no-notify-build] + use: buildx dockerfile: Dockerfile skip_push: false build_flag_templates: @@ -163,15 +141,13 @@ dockers: - "columnar/dbc:v{{ .Major }}.{{ .Minor }}-amd64" - "columnar/dbc:latest-amd64" use: buildx - ids: [no-notify-build] dockerfile: Dockerfile skip_push: auto build_flag_templates: - "--platform=linux/amd64" - image_templates: - "columnar/dbc:{{ .Version }}-arm64v8" - use: buildx - ids: [no-notify-build] + use: buildx goarch: arm64 dockerfile: Dockerfile skip_push: false @@ -182,8 +158,7 @@ dockers: - "columnar/dbc:v{{ .Major }}-arm64v8" - "columnar/dbc:v{{ .Major }}.{{ .Minor }}-arm64v8" - "columnar/dbc:latest-arm64v8" - use: buildx - ids: [no-notify-build] + use: buildx goarch: arm64 dockerfile: Dockerfile skip_push: auto @@ -232,8 +207,7 @@ docker_manifests: # path: ./resources/README.dockerhub.md nfpms: - - id: pkgs - ids: [no-notify-build] + - id: pkgs package_name: dbc file_name_template: "{{ .ConventionalFileName }}" if: '{{ eq .Os "linux" }}' @@ -261,8 +235,7 @@ nfpms: snapcrafts: - - id: snaps - ids: [no-notify-build] + - id: snaps name: dbc summary: The command line tool for installing and managing ADBC drivers description: The command line tool for installing and managing ADBC drivers @@ -286,8 +259,7 @@ snapcrafts: - $HOME/.config/adbc msi: - - id: msi - ids: [no-notify-build] + - id: msi name: "dbc-{{ .Version }}-{{ .MsiArch }}" wxs: ./resources/dbc.wxs extensions: @@ -340,7 +312,7 @@ homebrew_casks: - dbc@{{ .Version }} - dbc@{{ .Major }}.{{ .Minor }} ids: - - no-notify-archives + - archives url: template: "https://github.com/columnar-tech/dbc/releases/download/{{ .Tag }}/{{ .ArtifactName }}" verified: "github.com/columnar-tech/dbc/" diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index b9cea803..ac688dbf 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build !no_notify_latest - package main import ( "errors" "os" "path/filepath" + "runtime" + "strings" "charm.land/lipgloss/v2" "github.com/Masterminds/semver/v3" @@ -27,7 +27,54 @@ import ( "github.com/columnar-tech/dbc/internal" ) +func isPkgMgrInstall() bool { + exe, err := os.Executable() + if err != nil { + return false + } + + exe, err = filepath.EvalSymlinks(exe) + if err != nil { + return false + } + + switch filepath.Dir(exe) { + case "/opt/homebrew/bin", "/home/linuxbrew/.linuxbrew/bin": + // homebrew + return true + case "/usr/local/bin": + // homebrew on intel mac + // also pip installs here on linux + return true + case "/usr/bin": + // likely a system package manager, but could be other things too + return true + default: + // likely a local user install via script + // or via msi on windows etc. + // this is the case where we want to notify about updates + } + + if runtime.GOOS == "windows" && strings.HasSuffix(filepath.Dir(exe), "\\Scripts") { + // likely a pip install on windows + return true + } + + if strings.Contains(exe, "conda") || strings.Contains(exe, "venv") { + // likely a conda or virtual environment install + return true + } + + return false +} + func notifyLatest() { + if isPkgMgrInstall() { + // skip notifying if installed via package manager, + // since they likely have their own update mechanism + return + } + configDir, err := internal.GetDbcConfigPath() if err != nil { return diff --git a/cmd/dbc/latest_ignore.go b/cmd/dbc/latest_ignore.go deleted file mode 100644 index 7f1c63b3..00000000 --- a/cmd/dbc/latest_ignore.go +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2026 Columnar Technologies Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -//go:build no_notify_latest - -package main - -func notifyLatest() {} From 30f860408fa6984198efa8b7e999f1e998b9e952 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 12:33:00 -0400 Subject: [PATCH 11/21] trim trailing whitespace --- .goreleaser.yaml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 1b50596e..37092c3a 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -33,7 +33,7 @@ metadata: git: tag_sort: smartsemver -builds: +builds: - main: ./cmd/dbc binary: dbc ldflags: @@ -55,10 +55,10 @@ builds: post: - if: '{{ and (eq .Os "windows") (isEnvSet "SM_API_KEY") }}' cmd: >- - smctl sign --keypair-alias "{{ .Env.SM_KEYPAIR_ALIAS }}" --input "{{ .Path }}" --config-file "{{ .Env.PKCS11_CONFIG }}" + smctl sign --keypair-alias "{{ .Env.SM_KEYPAIR_ALIAS }}" --input "{{ .Path }}" --config-file "{{ .Env.PKCS11_CONFIG }}" -archives: - - id: archives +archives: + - id: archives formats: [tar.gz] # this name template makes the OS and Arch compatible with the results of `uname`. name_template: >- @@ -130,7 +130,7 @@ changelog: dockers: - image_templates: - "columnar/dbc:{{ .Version }}-amd64" - use: buildx + use: buildx dockerfile: Dockerfile skip_push: false build_flag_templates: @@ -147,7 +147,7 @@ dockers: - "--platform=linux/amd64" - image_templates: - "columnar/dbc:{{ .Version }}-arm64v8" - use: buildx + use: buildx goarch: arm64 dockerfile: Dockerfile skip_push: false @@ -158,7 +158,7 @@ dockers: - "columnar/dbc:v{{ .Major }}-arm64v8" - "columnar/dbc:v{{ .Major }}.{{ .Minor }}-arm64v8" - "columnar/dbc:latest-arm64v8" - use: buildx + use: buildx goarch: arm64 dockerfile: Dockerfile skip_push: auto @@ -207,7 +207,7 @@ docker_manifests: # path: ./resources/README.dockerhub.md nfpms: - - id: pkgs + - id: pkgs package_name: dbc file_name_template: "{{ .ConventionalFileName }}" if: '{{ eq .Os "linux" }}' @@ -235,7 +235,7 @@ nfpms: snapcrafts: - - id: snaps + - id: snaps name: dbc summary: The command line tool for installing and managing ADBC drivers description: The command line tool for installing and managing ADBC drivers @@ -259,7 +259,7 @@ snapcrafts: - $HOME/.config/adbc msi: - - id: msi + - id: msi name: "dbc-{{ .Version }}-{{ .MsiArch }}" wxs: ./resources/dbc.wxs extensions: From 54389caecdc30226d8e157e65f7e67453e2f2340 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 12:36:22 -0400 Subject: [PATCH 12/21] fix path --- internal/paths.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/paths.go b/internal/paths.go index 27b967cb..3de93cb7 100644 --- a/internal/paths.go +++ b/internal/paths.go @@ -56,7 +56,7 @@ func GetDbcConfigPath() (string, error) { if err != nil { return "", fmt.Errorf("failed to get user config directory: %w", err) } - return filepath.Join(userdir, "credentials", "credentials.toml"), nil + return userdir, nil default: // unix home, err := os.UserHomeDir() if err != nil { From d8f8a710dd780a835b1de77c1bd73801c00c70f0 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 12:38:43 -0400 Subject: [PATCH 13/21] fix macos config path --- internal/paths.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/paths.go b/internal/paths.go index 3de93cb7..09650c21 100644 --- a/internal/paths.go +++ b/internal/paths.go @@ -68,7 +68,7 @@ func GetDbcConfigPath() (string, error) { return "", errors.New("path in $XDG_DATA_HOME is relative") } - return dir, nil + return filepath.Join(dir, "dbc"), nil } // Directory for dbc credentials. This dir is distinct from GetUserConfigPath @@ -79,5 +79,5 @@ func GetCredentialPath() (string, error) { return "", fmt.Errorf("failed to get dbc config path: %w", err) } - return filepath.Join(dir, "dbc", "credentials", "credentials.toml"), nil + return filepath.Join(dir, "credentials", "credentials.toml"), nil } From b04dd37c9bc7e28044eed01989e5164493a524fb Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 16:05:08 -0400 Subject: [PATCH 14/21] check the brew prefix for comparison --- cmd/dbc/latest.go | 28 +++++++++++++++++++++++----- go.mod | 1 + go.sum | 2 ++ 3 files changed, 26 insertions(+), 5 deletions(-) diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index ac688dbf..060454ef 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -17,34 +17,52 @@ package main import ( "errors" "os" + "os/exec" "path/filepath" "runtime" "strings" "charm.land/lipgloss/v2" "github.com/Masterminds/semver/v3" + "github.com/cli/safeexec" "github.com/columnar-tech/dbc" "github.com/columnar-tech/dbc/internal" ) +func isUnderHomebrew(bin string) bool { + brewExe, err := safeexec.LookPath("brew") + if err != nil { + return false + } + + brewPrefixBytes, err := exec.Command(brewExe, "--prefix").Output() + if err != nil { + return false + } + + brewBinPrefix := filepath.Join(strings.TrimSpace( + string(brewPrefixBytes)), "bin") + string(filepath.Separator) + return strings.HasPrefix(bin, brewBinPrefix) +} + func isPkgMgrInstall() bool { exe, err := os.Executable() if err != nil { return false } + if isUnderHomebrew(exe) { + return true + } + exe, err = filepath.EvalSymlinks(exe) if err != nil { return false } switch filepath.Dir(exe) { - case "/opt/homebrew/bin", "/home/linuxbrew/.linuxbrew/bin": - // homebrew - return true case "/usr/local/bin": - // homebrew on intel mac - // also pip installs here on linux + // pip installs here on linux return true case "/usr/bin": // likely a system package manager, but could be other things too diff --git a/go.mod b/go.mod index 597ffa20..acdf162b 100644 --- a/go.mod +++ b/go.mod @@ -48,6 +48,7 @@ require ( github.com/charmbracelet/x/term v0.2.2 // indirect github.com/charmbracelet/x/termios v0.1.1 // indirect github.com/charmbracelet/x/windows v0.2.2 // indirect + github.com/cli/safeexec v1.0.1 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/cloudflare/circl v1.6.3 // indirect diff --git a/go.sum b/go.sum index 851cf605..749b2bb2 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,8 @@ github.com/cli/browser v1.3.0/go.mod h1:HH8s+fOAxjhQoBUAsKuPCbqUuxZDhQ2/aD+SzsEf github.com/cli/oauth v1.2.1 h1:9+vketSVuBCbEIpx4XPHHDlTX2R9MbLnM79sfA2Ac+4= github.com/cli/oauth v1.2.1/go.mod h1:qd/FX8ZBD6n1sVNQO3aIdRxeu5LGw9WhKnYhIIoC2A4= github.com/cli/safeexec v1.0.0/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= +github.com/cli/safeexec v1.0.1 h1:e/C79PbXF4yYTN/wauC4tviMxEV13BwljGj0N9j+N00= +github.com/cli/safeexec v1.0.1/go.mod h1:Z/D4tTN8Vs5gXYHDCbaM1S/anmEDnJb1iW0+EJ5zx3Q= github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0= github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk= From 91b62199a7108f73b537709e60c46bbb0b9db7a7 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 20:26:19 -0400 Subject: [PATCH 15/21] Update cmd/dbc/latest.go Co-authored-by: Bryce Mecum --- cmd/dbc/latest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index 060454ef..d5dbe149 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -105,7 +105,7 @@ func notifyLatest() { if dbc.Version != "(devel)" && err == nil { if semver.MustParse(dbc.Version).LessThan(latestVer) { lipgloss.Printf(descStyle.Render("Update available: A new version of dbc is available. You're running %s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), - dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") + dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/v"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") lipgloss.Println() } } From 490f173c3334381aeff1c9fd712ad77c957aa6e8 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Tue, 21 Apr 2026 20:26:49 -0400 Subject: [PATCH 16/21] Update cmd/dbc/latest.go Co-authored-by: Bryce Mecum --- cmd/dbc/latest.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index d5dbe149..d2a55532 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -104,7 +104,7 @@ func notifyLatest() { latestVer, err := dbc.GetLatestDbcVersion() if dbc.Version != "(devel)" && err == nil { if semver.MustParse(dbc.Version).LessThan(latestVer) { - lipgloss.Printf(descStyle.Render("Update available: A new version of dbc is available. You're running %s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), + lipgloss.Printf(descStyle.Render("Update available: A new version of dbc is available. You're running v%s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/v"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") lipgloss.Println() } From ac29758cf4e0f14c227df1098d94b5d10183a6cc Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 22 Apr 2026 17:26:28 -0400 Subject: [PATCH 17/21] updates from comments --- cmd/dbc/latest.go | 66 ++++++++++++++++++++++++--------------- cmd/dbc/latest_linux.go | 47 ++++++++++++++++++++++++++++ cmd/dbc/latest_windows.go | 46 +++++++++++++++++++++++++++ internal/paths.go | 19 +++-------- 4 files changed, 138 insertions(+), 40 deletions(-) create mode 100644 cmd/dbc/latest_linux.go create mode 100644 cmd/dbc/latest_windows.go diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index d2a55532..542ca5dc 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -19,8 +19,8 @@ import ( "os" "os/exec" "path/filepath" - "runtime" "strings" + "time" "charm.land/lipgloss/v2" "github.com/Masterminds/semver/v3" @@ -60,25 +60,11 @@ func isPkgMgrInstall() bool { return false } - switch filepath.Dir(exe) { - case "/usr/local/bin": - // pip installs here on linux - return true - case "/usr/bin": - // likely a system package manager, but could be other things too - return true - default: - // likely a local user install via script - // or via msi on windows etc. - // this is the case where we want to notify about updates - } - - if runtime.GOOS == "windows" && strings.HasSuffix(filepath.Dir(exe), "\\Scripts") { - // likely a pip install on windows + if isManaged(exe) { return true } - if strings.Contains(exe, "conda") || strings.Contains(exe, "venv") { + if strings.Contains(exe, "conda") || strings.Contains(exe, "venv") || strings.Contains(exe, "miniforge") { // likely a conda or virtual environment install return true } @@ -86,27 +72,55 @@ func isPkgMgrInstall() bool { return false } -func notifyLatest() { - if isPkgMgrInstall() { - // skip notifying if installed via package manager, - // since they likely have their own update mechanism - return - } +func writeLastUpdateCheck(configDir string) { + // file doesn't exist, create it with current timestamp and skip update check + _ = os.MkdirAll(configDir, 0o700) + _ = os.WriteFile(filepath.Join(configDir, ".last-update-check"), []byte(time.Now().Format(time.DateOnly)), 0o600) +} - configDir, err := internal.GetDbcConfigPath() +func notifyLatest() { + configDir, err := internal.GetUserConfigPath() if err != nil { return } // skip notifying if $dbc_config_home/.no-update exists _, err = os.Stat(filepath.Join(configDir, ".no-update")) + if err == nil { + return // file exists, skip update check + } + + lastUpdate, err := os.ReadFile(filepath.Join(configDir, ".last-update-check")) + if errors.Is(err, os.ErrNotExist) { + writeLastUpdateCheck(configDir) + } else if err == nil { + lastCheckTime, err := time.Parse(time.DateOnly, string(lastUpdate)) + if err != nil { + // if the file is corrupted, reset it + _ = os.WriteFile(filepath.Join(configDir, ".last-update-check"), []byte(time.Now().Format(time.DateOnly)), 0o600) + return + } + + if time.Since(lastCheckTime) > 24*time.Hour { + writeLastUpdateCheck(configDir) + } else { + return // last check was within 24 hours, skip update check + } + } + + if isPkgMgrInstall() { + // skip notifying if installed via package manager, + // since they likely have their own update mechanism + return + } + if errors.Is(err, os.ErrNotExist) { latestVer, err := dbc.GetLatestDbcVersion() if dbc.Version != "(devel)" && err == nil { if semver.MustParse(dbc.Version).LessThan(latestVer) { - lipgloss.Printf(descStyle.Render("Update available: A new version of dbc is available. You're running v%s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), + lipgloss.Fprintf(os.Stderr, descStyle.Render("Update available: A new version of dbc is available. You're running v%s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/v"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") - lipgloss.Println() + lipgloss.Fprintln(os.Stderr) } } } diff --git a/cmd/dbc/latest_linux.go b/cmd/dbc/latest_linux.go new file mode 100644 index 00000000..457f26dc --- /dev/null +++ b/cmd/dbc/latest_linux.go @@ -0,0 +1,47 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build linux + +package main + +import ( + "os/exec" + "path/filepath" +) + +func isManaged(exe string) bool { + // check if we're a deb install + dpkgExe, err := exec.LookPath("dpkg") + if err == nil { + if err = exec.Command(dpkgExe, "-S", exe).Run(); err == nil { + return true + } + } + + // check if we're an rpm install + rpmExe, err := exec.LookPath("rpm") + if err == nil { + if err = exec.Command(rpmExe, "-qf", exe).Run(); err == nil { + return true + } + } + + if filepath.Dir(exe) == "/usr/local/bin" { + // pip installs here on linux + return true + } + + return false +} diff --git a/cmd/dbc/latest_windows.go b/cmd/dbc/latest_windows.go new file mode 100644 index 00000000..1caef3e4 --- /dev/null +++ b/cmd/dbc/latest_windows.go @@ -0,0 +1,46 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build windows + +package main + +import ( + "path/filepath" + "strings" + + "golang.org/x/sys/windows/registry" +) + +func isManaged(exe string) bool { + const packedUpgradeCode = `F0742CB3EE450F7479C37A9886B49FE5` + const registryPath = `SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UpgradeCodes\` + packedUpgradeCode + + k, err := registry.OpenKey(registry.LOCAL_MACHINE, registryPath, registry.QUERY_VALUE) + if err == nil { + // If we can open the key, check if our executable is listed as an installed product under this upgrade code + // this means dbc is installed via MSI. + defer k.Close() + + // so check if we're running from the location where dbc.msi installs to + return strings.Contains(exe, `AppData\Roaming\Columnar\dbc`) + } + + if strings.HasSuffix(filepath.Dir(exe), "\\Scripts") { + // likely a pip install + return true + } + + return false +} diff --git a/internal/paths.go b/internal/paths.go index 09650c21..71bc908b 100644 --- a/internal/paths.go +++ b/internal/paths.go @@ -41,7 +41,9 @@ func GetUserConfigPath() (string, error) { return finalDir, nil } -func GetDbcConfigPath() (string, error) { +// Directory for dbc credentials. This dir is distinct from GetUserConfigPath +// except for on macOS where it's the same +func GetCredentialPath() (string, error) { dir := os.Getenv("XDG_DATA_HOME") if dir == "" { switch runtime.GOOS { @@ -56,7 +58,7 @@ func GetDbcConfigPath() (string, error) { if err != nil { return "", fmt.Errorf("failed to get user config directory: %w", err) } - return userdir, nil + return filepath.Join(userdir, "credentials", "credentials.toml"), nil default: // unix home, err := os.UserHomeDir() if err != nil { @@ -68,16 +70,5 @@ func GetDbcConfigPath() (string, error) { return "", errors.New("path in $XDG_DATA_HOME is relative") } - return filepath.Join(dir, "dbc"), nil -} - -// Directory for dbc credentials. This dir is distinct from GetUserConfigPath -// except for on macOS where it's the same -func GetCredentialPath() (string, error) { - dir, err := GetDbcConfigPath() - if err != nil { - return "", fmt.Errorf("failed to get dbc config path: %w", err) - } - - return filepath.Join(dir, "credentials", "credentials.toml"), nil + return filepath.Join(dir, "dbc", "credentials", "credentials.toml"), nil } From 6142e98efec24254575282ce6e12b0be68873074 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 22 Apr 2026 17:26:42 -0400 Subject: [PATCH 18/21] put comment back --- .goreleaser.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 37092c3a..9ddb03aa 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -52,7 +52,9 @@ builds: goarch: arm64 mod_timestamp: "{{ .CommitTimestamp }}" hooks: - post: + post: # sign the windows binaries in-place with smctl, which is required + # for the Microsoft Store. We don't produce detached signatures for + # windows binaries since that's not really a thing on windows and smctl doesn't support it. - if: '{{ and (eq .Os "windows") (isEnvSet "SM_API_KEY") }}' cmd: >- smctl sign --keypair-alias "{{ .Env.SM_KEYPAIR_ALIAS }}" --input "{{ .Path }}" --config-file "{{ .Env.PKCS11_CONFIG }}" From 7bb90e8aebcbe8bd4c98bea92e098551738ca1a7 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 22 Apr 2026 17:28:28 -0400 Subject: [PATCH 19/21] fix trailing whitespace --- .goreleaser.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.goreleaser.yaml b/.goreleaser.yaml index 9ddb03aa..e2d27ea0 100644 --- a/.goreleaser.yaml +++ b/.goreleaser.yaml @@ -52,8 +52,8 @@ builds: goarch: arm64 mod_timestamp: "{{ .CommitTimestamp }}" hooks: - post: # sign the windows binaries in-place with smctl, which is required - # for the Microsoft Store. We don't produce detached signatures for + post: # sign the windows binaries in-place with smctl, which is required + # for the Microsoft Store. We don't produce detached signatures for # windows binaries since that's not really a thing on windows and smctl doesn't support it. - if: '{{ and (eq .Os "windows") (isEnvSet "SM_API_KEY") }}' cmd: >- From 88159f8418006d380385f4470866e6061c60099e Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 22 Apr 2026 17:30:25 -0400 Subject: [PATCH 20/21] add macos check --- cmd/dbc/latest_darwin.go | 26 ++++++++++++++++++++++++++ cmd/dbc/latest_linux.go | 2 -- cmd/dbc/latest_windows.go | 2 -- 3 files changed, 26 insertions(+), 4 deletions(-) create mode 100644 cmd/dbc/latest_darwin.go diff --git a/cmd/dbc/latest_darwin.go b/cmd/dbc/latest_darwin.go new file mode 100644 index 00000000..48de62d7 --- /dev/null +++ b/cmd/dbc/latest_darwin.go @@ -0,0 +1,26 @@ +// Copyright 2026 Columnar Technologies Inc. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import "path/filepath" + +func isManaged(exe string) bool { + if filepath.Dir(exe) == "/usr/local/bin" { + // system-wide pip install + return true + } + + return false +} diff --git a/cmd/dbc/latest_linux.go b/cmd/dbc/latest_linux.go index 457f26dc..9875ac9b 100644 --- a/cmd/dbc/latest_linux.go +++ b/cmd/dbc/latest_linux.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build linux - package main import ( diff --git a/cmd/dbc/latest_windows.go b/cmd/dbc/latest_windows.go index 1caef3e4..6119b558 100644 --- a/cmd/dbc/latest_windows.go +++ b/cmd/dbc/latest_windows.go @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build windows - package main import ( From d37a0943b18037efdfe7b6a48f2f0700c9a25d02 Mon Sep 17 00:00:00 2001 From: Matt Topol Date: Wed, 22 Apr 2026 17:44:02 -0400 Subject: [PATCH 21/21] fix logic --- cmd/dbc/latest.go | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/cmd/dbc/latest.go b/cmd/dbc/latest.go index 542ca5dc..018b3898 100644 --- a/cmd/dbc/latest.go +++ b/cmd/dbc/latest.go @@ -98,10 +98,7 @@ func notifyLatest() { if err != nil { // if the file is corrupted, reset it _ = os.WriteFile(filepath.Join(configDir, ".last-update-check"), []byte(time.Now().Format(time.DateOnly)), 0o600) - return - } - - if time.Since(lastCheckTime) > 24*time.Hour { + } else if time.Since(lastCheckTime) > 24*time.Hour { writeLastUpdateCheck(configDir) } else { return // last check was within 24 hours, skip update check @@ -114,14 +111,12 @@ func notifyLatest() { return } - if errors.Is(err, os.ErrNotExist) { - latestVer, err := dbc.GetLatestDbcVersion() - if dbc.Version != "(devel)" && err == nil { - if semver.MustParse(dbc.Version).LessThan(latestVer) { - lipgloss.Fprintf(os.Stderr, descStyle.Render("Update available: A new version of dbc is available. You're running v%s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), - dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/v"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") - lipgloss.Fprintln(os.Stderr) - } + latestVer, err := dbc.GetLatestDbcVersion() + if dbc.Version != "(devel)" && err == nil { + if semver.MustParse(dbc.Version).LessThan(latestVer) { + lipgloss.Fprintf(os.Stderr, descStyle.Render("Update available: A new version of dbc is available. You're running v%s and v%s is available. Please upgrade.\nChangelog: %s. Docs: %s"), + dbc.Version, latestVer, "https://github.com/columnar-tech/dbc/releases/tag/v"+latestVer.String(), "https://docs.columnar.tech/dbc/getting_started/installation/") + lipgloss.Fprintln(os.Stderr) } } }