Hello,
I'd like to propose keeping the OpenBSD-specific changes required for
the survey module directly in the ports tree instead of using a separate
fork.
The attached diff removes the patched survey fork from DIST_TUPLE and
uses the original upstream survey module already fetched as part of the
Go dependency set. The required OpenBSD changes are then applied from
devel/github-cli/files during the port build.
The main reason for this approach is maintainability. The divergence
from upstream is relatively small, so keeping it as normal ports patches
makes the OpenBSD-specific changes immediately visible alongside the
port that requires them.
It should also make future github-cli updates easier. When the survey
dependency changes, the patches can be tested directly against the new
upstream version and refreshed or removed if they are no longer needed,
without having to maintain and update a separate fork first.
There is also a preservation advantage. By keeping the required changes
in the official ports tree, they remain part of the OpenBSD ports
history. If an external fork were abandoned or disappeared in the
future, the changes required to make the module work on OpenBSD would
not be lost with it.
In this case, the port uses the upstream survey v2.3.7 module and adds
the OpenBSD-specific changes as local patches.
The terminal code is changed to use the ioctl(2) wrappers provided by
golang.org/x/sys/unix instead of syscall.Syscall6, and go.mod is adjusted
for the additional x/sys dependency.
I think this is simpler and more sustainable than maintaining a separate
fork for a small OpenBSD-specific portability change.
Patch attached.
Thank you for your time and consideration.
Best regards,
David.
Index: devel/github-cli/Makefile
===================================================================
RCS file: /cvs/ports/devel/github-cli/Makefile,v
diff -u -p -u -p -r1.82 Makefile
--- devel/github-cli/Makefile 21 Sep 2026 22:58:28 -0000 1.82
+++ devel/github-cli/Makefile 28 Sep 2026 15:56:03 -0000
@@ -7,11 +7,11 @@ MODGO_VERSION = v${V}
DISTNAME = cli-${MODGO_VERSION}
PKGNAME = github-cli-${V}
-# replace "survey" module with a patched version that uses ioctl
-# instead of unnecessary direct syscall() calls
-SURVEY_V = vv2.3.8
-DIST_TUPLE = github bsdmp survey ${SURVEY_V} ../survey
-EXTRACT_ONLY = bsdmp-survey-${SURVEY_V}.tar.gz
+# The survey module still uses the indirect syscall(2) interface for
+# termios, which OpenBSD 7.5 removed (golang/go#63900). Patch the module
+# source from its distfile instead of fetching a fork.
+SURVEY_MOD = github.com/!alec!aivazis/survey/v2
+SURVEY_V = v2.3.7
CATEGORIES = devel
HOMEPAGE = https://cli.github.com/
@@ -29,6 +29,19 @@ MODGO_LDFLAGS += -X "${MODGO_MODNAME}/in
TEST_TARGET = ./...
PORTHOME = ${WRKDIR}
+
+post-extract:
+ ${UNZIP} -oq ${DISTDIR}/go_modules/${SURVEY_MOD}/@v/${SURVEY_V}.zip \
+ -d ${WRKDIR}/survey-extract
+ mv ${WRKDIR}/survey-extract/github.com/AlecAivazis/survey/v2@${SURVEY_V} \
+ ${WRKDIR}/survey
+ rm -rf ${WRKDIR}/survey-extract
+
+post-patch:
+ patch -d ${WRKDIR}/survey -p0 \
+ < ${FILESDIR}/patch-survey_terminal_runereader_posix_go
+ patch -d ${WRKDIR}/survey -p0 \
+ < ${FILESDIR}/patch-survey_go_mod
pre-build:
cd ${WRKSRC}; ${MODGO_CMD} mod edit -replace \
Index: devel/github-cli/distinfo
===================================================================
RCS file: /cvs/ports/devel/github-cli/distinfo,v
diff -u -p -u -p -r1.73 distinfo
--- devel/github-cli/distinfo 21 Sep 2026 22:58:28 -0000 1.73
+++ devel/github-cli/distinfo 28 Sep 2026 15:56:03 -0000
@@ -1,4 +1,3 @@
-SHA256 (bsdmp-survey-vv2.3.8.tar.gz) = fPcSUSZ4Kkovs52dRmmAtg+lX8R/EDkhLaLMZJCphMU=
SHA256 (cli-v2.101.0.zip) = SLs5klYDMaHMpiu5/IT/75+4b1K7A0YikzdUo/9sM60=
SHA256 (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.mod) = p5DeefOWpGgRzfiXR7IMnJJZnIfIuiXfICeZ+ODldMk=
SHA256 (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.zip) = KW2htHeMHqh5EXGvsVathbPZsI2eiI1Wh66jJt2/wyo=
@@ -1310,7 +1309,6 @@ SHA256 (go_modules/sigs.k8s.io/yaml/@v/v
SHA256 (go_modules/sigs.k8s.io/yaml/@v/v1.6.0.zip) = z4hkikcVgYF7AKQu6NJP1z6w41A5mM9G2OY3h+EeUFI=
SHA256 (go_modules/software.sslmate.com/src/go-pkcs12/@v/v0.4.0.mod) = +/Vbaah9WjkQgv2brl5MdYEEH+Cbi7k7D+Fs3f6FzpU=
SHA256 (go_modules/software.sslmate.com/src/go-pkcs12/@v/v0.4.0.zip) = VQGaOR5TAqUbpi6YkJ4AYiS4EgeGbakL6vWC7A3uA28=
-SIZE (bsdmp-survey-vv2.3.8.tar.gz) = 125803
SIZE (cli-v2.101.0.zip) = 16062085
SIZE (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.mod) = 89
SIZE (go_modules/bitbucket.org/creachadair/shell/@v/v0.0.8.zip) = 8712
Index: devel/github-cli/files/patch-survey_go_mod
===================================================================
RCS file: devel/github-cli/files/patch-survey_go_mod
diff -N devel/github-cli/files/patch-survey_go_mod
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ devel/github-cli/files/patch-survey_go_mod 28 Sep 2026 15:56:03 -0000
@@ -0,0 +1,13 @@
+Require golang.org/x/sys, imported by the patched terminal code.
+
+Index: go.mod
+--- go.mod.orig
++++ go.mod
+@@ -10,6 +10,7 @@
+ github.com/mattn/go-isatty v0.0.8
+ github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b
+ github.com/stretchr/testify v1.6.1
++ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f
+ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
+ golang.org/x/text v0.4.0
+ )
Index: devel/github-cli/files/patch-survey_terminal_runereader_posix_go
===================================================================
RCS file: devel/github-cli/files/patch-survey_terminal_runereader_posix_go
diff -N devel/github-cli/files/patch-survey_terminal_runereader_posix_go
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ devel/github-cli/files/patch-survey_terminal_runereader_posix_go 28 Sep 2026 15:56:03 -0000
@@ -0,0 +1,63 @@
+Use ioctl(2) through golang.org/x/sys/unix instead of the indirect
+syscall(2) interface. OpenBSD 7.5 removed indirect system calls and Go
+only reroutes the three-argument syscall.Syscall form of SYS_IOCTL to
+the libc stub, so the syscall.Syscall6 calls used here fail with ENOSYS
+(golang/go#63900).
+
+Index: terminal/runereader_posix.go
+--- terminal/runereader_posix.go.orig
++++ terminal/runereader_posix.go
+@@ -14,7 +14,7 @@
+ "bytes"
+ "fmt"
+ "syscall"
+- "unsafe"
++ "golang.org/x/sys/unix"
+ )
+
+ const (
+@@ -23,7 +23,7 @@
+ )
+
+ type runeReaderState struct {
+- term syscall.Termios
++ term unix.Termios
+ reader *bufio.Reader
+ buf *bytes.Buffer
+ }
+@@ -45,19 +45,20 @@
+
+ // For reading runes we just want to disable echo.
+ func (rr *RuneReader) SetTermMode() error {
+- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(rr.stdio.In.Fd()), ioctlReadTermios, uintptr(unsafe.Pointer(&rr.state.term)), 0, 0, 0); err != 0 {
++ termios, err := unix.IoctlGetTermios((int)(rr.stdio.In.Fd()), ioctlReadTermios)
++ if err != nil {
+ return err
+ }
+
+- newState := rr.state.term
+- newState.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG
++ rr.state.term = *termios
++ termios.Lflag &^= syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG
+ // Because we are clearing canonical mode, we need to ensure VMIN & VTIME are
+ // set to the values we expect. This combination puts things in standard
+ // "blocking read" mode (see termios(3)).
+- newState.Cc[syscall.VMIN] = 1
+- newState.Cc[syscall.VTIME] = 0
++ termios.Cc[syscall.VMIN] = 1
++ termios.Cc[syscall.VTIME] = 0
+
+- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(rr.stdio.In.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&newState)), 0, 0, 0); err != 0 {
++ if err = unix.IoctlSetTermios((int)(rr.stdio.In.Fd()), ioctlWriteTermios, termios); err != nil {
+ return err
+ }
+
+@@ -65,7 +66,7 @@
+ }
+
+ func (rr *RuneReader) RestoreTermMode() error {
+- if _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(rr.stdio.In.Fd()), ioctlWriteTermios, uintptr(unsafe.Pointer(&rr.state.term)), 0, 0, 0); err != 0 {
++ if err := unix.IoctlSetTermios((int)(rr.stdio.In.Fd()), ioctlWriteTermios, &rr.state.term); err != nil {
+ return err
+ }
+ return nil