diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000..69aeab9ae --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,8 @@ +version: "2" + +run: + timeout: 10m + +linters: + disable: + - govet \ No newline at end of file diff --git a/Makefile b/Makefile index 9a8ba3c81..6638ec72c 100644 --- a/Makefile +++ b/Makefile @@ -93,7 +93,7 @@ fmt: # Run golangci-lint against code .PHONY: lint lint: $(TOOLS_BINDIR)/golangci-lint - "$(TOOLS_BINDIR)"/golangci-lint run -v --timeout 10m + "$(TOOLS_BINDIR)"/golangci-lint run -v .PHONY: renovate-check renovate-check: diff --git a/go.mod b/go.mod index 4eeafdd7c..20eca84d5 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/coocood/freecache v1.2.7 github.com/pulumi/pulumi-command/sdk v1.2.1 github.com/pulumi/pulumi-random/sdk/v4 v4.19.2 - github.com/pulumi/pulumi/sdk/v3 v3.232.0 + github.com/pulumi/pulumi/sdk/v3 v3.234.0 github.com/sirupsen/logrus v1.9.4 github.com/spf13/cobra v1.10.2 ) @@ -26,11 +26,11 @@ require ( github.com/aws/amazon-ec2-instance-selector/v3 v3.1.3 github.com/aws/aws-sdk-go-v2 v1.41.7 github.com/aws/aws-sdk-go-v2/config v1.32.17 - github.com/aws/aws-sdk-go-v2/service/ec2 v1.299.1 + github.com/aws/aws-sdk-go-v2/service/ec2 v1.300.0 github.com/aws/aws-sdk-go-v2/service/s3 v1.100.1 github.com/aws/aws-sdk-go-v2/service/sts v1.42.1 - github.com/pulumi/pulumi-aws-native/sdk v1.62.0 - github.com/pulumi/pulumi-aws/sdk/v7 v7.27.0 + github.com/pulumi/pulumi-aws-native/sdk v1.63.0 + github.com/pulumi/pulumi-aws/sdk/v7 v7.28.0 github.com/pulumi/pulumi-awsx/sdk/v3 v3.5.0 github.com/pulumi/pulumi-azure-native-sdk/authorization/v3 v3.17.0 github.com/pulumi/pulumi-azure-native-sdk/compute/v3 v3.17.0 @@ -102,7 +102,7 @@ require ( github.com/charmbracelet/lipgloss v1.1.0 // indirect github.com/charmbracelet/x/ansi v0.11.7 // indirect github.com/charmbracelet/x/cellbuf v0.0.15 // indirect - github.com/charmbracelet/x/exp/golden v0.0.0-20260427100455-1ea3e7f8134f // indirect + github.com/charmbracelet/x/exp/golden v0.0.0-20260503005035-c113ba3d2310 // indirect github.com/charmbracelet/x/term v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect @@ -137,7 +137,7 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/pelletier/go-toml/v2 v2.3.1 // indirect github.com/pgavlin/fx v0.1.6 // indirect - github.com/pjbgf/sha1cd v0.5.0 // indirect + github.com/pjbgf/sha1cd v0.6.0 // indirect github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c // indirect github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 // indirect github.com/pulumi/esc v0.23.0 // indirect @@ -152,7 +152,7 @@ require ( github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/zclconf/go-cty v1.18.1 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect - go.opentelemetry.io/collector/featuregate v1.56.0 // indirect + go.opentelemetry.io/collector/featuregate v1.57.0 // indirect go.opentelemetry.io/collector/pdata v1.56.0 // indirect go.opentelemetry.io/otel v1.43.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.43.0 // indirect @@ -167,12 +167,12 @@ require ( golang.org/x/oauth2 v0.36.0 // indirect golang.org/x/sync v0.20.0 // indirect golang.org/x/time v0.15.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20260420184626-e10c466a9529 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/klog/v2 v2.140.0 // indirect - k8s.io/kube-openapi v0.0.0-20260414162039-ec9c827d403f // indirect + k8s.io/kube-openapi v0.0.0-20260504175024-7bfe71ffdc10 // indirect k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect @@ -190,7 +190,7 @@ require ( github.com/cheggaaa/pb v1.0.29 // indirect github.com/djherbis/times v1.6.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect - github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fsnotify/fsnotify v1.10.1 // indirect github.com/go-git/go-billy/v5 v5.8.0 // indirect github.com/go-git/go-git/v5 v5.18.0 // indirect github.com/go-playground/validator/v10 v10.30.2 @@ -224,7 +224,7 @@ require ( golang.org/x/sys v0.43.0 // indirect golang.org/x/term v0.42.0 // indirect golang.org/x/text v0.36.0 // indirect - google.golang.org/grpc v1.80.0 // indirect + google.golang.org/grpc v1.81.0 // indirect google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect diff --git a/go.sum b/go.sum index bce44a0d6..03f8aa002 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23 h1:bpd8vxhlQi2r1hiueO github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.7.23/go.mod h1:15DfR2nw+CRHIk0tqNyifu3G1YdAOy68RftkhMDDwYk= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24 h1:OQqn11BtaYv1WLUowvcA30MpzIu8Ti4pcLPIIyoKZrA= github.com/aws/aws-sdk-go-v2/internal/v4a v1.4.24/go.mod h1:X5ZJyfwVrWA96GzPmUCWFQaEARPR7gCrpq2E92PJwAE= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.299.1 h1:gQ9fSyFk3Y9Vm2fVbphBeJfXJlkJvEvC35TszBVjprg= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.299.1/go.mod h1:Y95W0Hm6FYLPa6o0hbnJ+sWgmdc4ifcLFjGkdobWVhY= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.300.0 h1:HgOfUy9Sm2Q9UQAyj9I/7NZhIaymTEakGA/FnLw65lw= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.300.0/go.mod h1:Y95W0Hm6FYLPa6o0hbnJ+sWgmdc4ifcLFjGkdobWVhY= github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1 h1:tQNU4tC4cMoZo1e+7J8j3/GWM7PJFdXCN0VzEFwFqUE= github.com/aws/aws-sdk-go-v2/service/ecs v1.79.1/go.mod h1:TIKZ9zIFS6W2k9FeW+r5sGVnlxp+aUt9oQ/St3Suj1o= github.com/aws/aws-sdk-go-v2/service/iam v1.53.10 h1:kcN3I3llO7VwIY5w3Pc5FmEonpsr23Ou7Cwk4qf7dik= @@ -121,8 +121,8 @@ github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dA github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ= github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= -github.com/charmbracelet/x/exp/golden v0.0.0-20260427100455-1ea3e7f8134f h1:W1dl4Koqo1MF76W+dX8gsryCBw2qoQjnU7v3+7oddhs= -github.com/charmbracelet/x/exp/golden v0.0.0-20260427100455-1ea3e7f8134f/go.mod h1:6fMpcW6iwN/kX+xJ52eqVWsDiBTe0UJD24JLoHFe+P0= +github.com/charmbracelet/x/exp/golden v0.0.0-20260503005035-c113ba3d2310 h1:qqdg2P7LPgzQXZLzwAghIJnDGLo+vjhwfhXTp+tYF5E= +github.com/charmbracelet/x/exp/golden v0.0.0-20260503005035-c113ba3d2310/go.mod h1:6fMpcW6iwN/kX+xJ52eqVWsDiBTe0UJD24JLoHFe+P0= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= github.com/cheggaaa/pb v1.0.29 h1:FckUN5ngEk2LpvuG0fw1GEFx6LtyY2pWI/Z2QgCnEYo= @@ -160,8 +160,8 @@ github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLg github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= +github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= github.com/fxamacker/cbor/v2 v2.9.1 h1:2rWm8B193Ll4VdjsJY28jxs70IdDsHRWgQYAI80+rMQ= github.com/fxamacker/cbor/v2 v2.9.1/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM= @@ -193,8 +193,30 @@ github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1 github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= -github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= +github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= +github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= +github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= +github.com/go-openapi/swag/cmdutils v0.25.4/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= +github.com/go-openapi/swag/conv v0.25.4 h1:/Dd7p0LZXczgUcC/Ikm1+YqVzkEeCc9LnOWjfkpkfe4= +github.com/go-openapi/swag/conv v0.25.4/go.mod h1:3LXfie/lwoAv0NHoEuY1hjoFAYkvlqI/Bn5EQDD3PPU= +github.com/go-openapi/swag/fileutils v0.25.4 h1:2oI0XNW5y6UWZTC7vAxC8hmsK/tOkWXHJQH4lKjqw+Y= +github.com/go-openapi/swag/fileutils v0.25.4/go.mod h1:cdOT/PKbwcysVQ9Tpr0q20lQKH7MGhOEb6EwmHOirUk= +github.com/go-openapi/swag/jsonname v0.25.4 h1:bZH0+MsS03MbnwBXYhuTttMOqk+5KcQ9869Vye1bNHI= +github.com/go-openapi/swag/jsonname v0.25.4/go.mod h1:GPVEk9CWVhNvWhZgrnvRA6utbAltopbKwDu8mXNUMag= +github.com/go-openapi/swag/jsonutils v0.25.4 h1:VSchfbGhD4UTf4vCdR2F4TLBdLwHyUDTd1/q4i+jGZA= +github.com/go-openapi/swag/jsonutils v0.25.4/go.mod h1:7OYGXpvVFPn4PpaSdPHJBtF0iGnbEaTk8AvBkoWnaAY= +github.com/go-openapi/swag/loading v0.25.4 h1:jN4MvLj0X6yhCDduRsxDDw1aHe+ZWoLjW+9ZQWIKn2s= +github.com/go-openapi/swag/loading v0.25.4/go.mod h1:rpUM1ZiyEP9+mNLIQUdMiD7dCETXvkkC30z53i+ftTE= +github.com/go-openapi/swag/mangling v0.25.4 h1:2b9kBJk9JvPgxr36V23FxJLdwBrpijI26Bx5JH4Hp48= +github.com/go-openapi/swag/mangling v0.25.4/go.mod h1:6dxwu6QyORHpIIApsdZgb6wBk/DPU15MdyYj/ikn0Hg= +github.com/go-openapi/swag/netutils v0.25.4 h1:Gqe6K71bGRb3ZQLusdI8p/y1KLgV4M/k+/HzVSqT8H0= +github.com/go-openapi/swag/netutils v0.25.4/go.mod h1:m2W8dtdaoX7oj9rEttLyTeEFFEBvnAx9qHd5nJEBzYg= +github.com/go-openapi/swag/stringutils v0.25.4 h1:O6dU1Rd8bej4HPA3/CLPciNBBDwZj9HiEpdVsb8B5A8= +github.com/go-openapi/swag/stringutils v0.25.4/go.mod h1:GTsRvhJW5xM5gkgiFe0fV3PUlFm0dr8vki6/VSRaZK0= +github.com/go-openapi/swag/typeutils v0.25.4 h1:1/fbZOUN472NTc39zpa+YGHn3jzHWhv42wAJSN91wRw= +github.com/go-openapi/swag/typeutils v0.25.4/go.mod h1:Ou7g//Wx8tTLS9vG0UmzfCsjZjKhpjxayRKTHXf2pTE= +github.com/go-openapi/swag/yamlutils v0.25.4 h1:6jdaeSItEUb7ioS9lFoCZ65Cne1/RZtPBZ9A56h92Sw= +github.com/go-openapi/swag/yamlutils v0.25.4/go.mod h1:MNzq1ulQu+yd8Kl7wPOut/YHAAU/H6hL91fF+E2RFwc= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -240,8 +262,6 @@ github.com/iwdgo/sigintwindows v0.2.2 h1:P6oWzpvV7MrEAmhUgs+zmarrWkyL77ycZz4v7+1 github.com/iwdgo/sigintwindows v0.2.2/go.mod h1:70wPb8oz8OnxPvsj2QMUjgIVhb8hMu5TUgX8KfFl7QY= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/kevinburke/ssh_config v1.6.0 h1:J1FBfmuVosPHf5GRdltRLhPJtJpTlMdKTBjRgTaQBFY= @@ -268,8 +288,6 @@ github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= github.com/lucasb-eyer/go-colorful v1.4.0 h1:UtrWVfLdarDgc44HcS7pYloGHJUjHV/4FwW4TvVgFr4= github.com/lucasb-eyer/go-colorful v1.4.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= @@ -324,8 +342,8 @@ github.com/pgavlin/fx v0.1.6 h1:r9jEg69DhNoCd3Xh0+5mIbdbS3PqWrVWujkY76MFRTU= github.com/pgavlin/fx v0.1.6/go.mod h1:KWZJ6fqBBSh8GxHYqwYCf3rYE7Gp2p0N8tJp8xv9u9M= github.com/pgavlin/fx/v2 v2.0.12 h1:SjjaJ68Dt8Z4zHwOpY/RPijd7lShs6xYupJbF9ra00M= github.com/pgavlin/fx/v2 v2.0.12/go.mod h1:M/nF/ooAOy+NUBooYYXl2REARzJ/giPJxfMs8fINfKc= -github.com/pjbgf/sha1cd v0.5.0 h1:a+UkboSi1znleCDUNT3M5YxjOnN1fz2FhN48FlwCxs0= -github.com/pjbgf/sha1cd v0.5.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= +github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU= +github.com/pjbgf/sha1cd v0.6.0/go.mod h1:lhpGlyHLpQZoxMv8HcgXvZEhcGs0PG/vsZnEJ7H0iCM= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c h1:+mdjkGKdHQG3305AYmdv1U2eRNDiU2ErMBj1gwrq8eQ= github.com/pkg/browser v0.0.0-20240102092130-5ac0b6a4141c/go.mod h1:7rwL4CYBLnjLxUqIJNnCWiEdr3bn6IUYi15bNlnbCCU= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -339,10 +357,10 @@ github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231 h1:vkHw5I/plNdTr435 github.com/pulumi/appdash v0.0.0-20231130102222-75f619a67231/go.mod h1:murToZ2N9hNJzewjHBgfFdXhZKjY3z5cYC1VXk+lbFE= github.com/pulumi/esc v0.23.0 h1:5lOXO+5vvXOEQxXw7cTuYhjg9lVng23f9XNLWDR9EP4= github.com/pulumi/esc v0.23.0/go.mod h1:mkghIFn/TvN3XnP4jmCB4U5BG1I4UjGluARi39ckrCE= -github.com/pulumi/pulumi-aws-native/sdk v1.62.0 h1:VrxS/9bsvBU9rIFwpjWNqcgsV4BnovUmmk7OobNqrHc= -github.com/pulumi/pulumi-aws-native/sdk v1.62.0/go.mod h1:08HfiYFanToWN1uRzHgjoXUNGyzKG3vHthcmZ/a1s5A= -github.com/pulumi/pulumi-aws/sdk/v7 v7.27.0 h1:zMt6jWMMCN1MP/Wxa4CeDw1VcLiM0V4wTvLBRd8bywM= -github.com/pulumi/pulumi-aws/sdk/v7 v7.27.0/go.mod h1:MvfGxMurVnahZ4UtHSxvjuoytba7IsojtbsplqlXhdg= +github.com/pulumi/pulumi-aws-native/sdk v1.63.0 h1:dHb9Py3IPAi1RPwQbWcAs90y1Ytu65fQ3b5Zo+Riuoo= +github.com/pulumi/pulumi-aws-native/sdk v1.63.0/go.mod h1:08HfiYFanToWN1uRzHgjoXUNGyzKG3vHthcmZ/a1s5A= +github.com/pulumi/pulumi-aws/sdk/v7 v7.28.0 h1:dN3702SraCmSuSLXK5TJMQXvxq8HZGfE/4iCo9PKftk= +github.com/pulumi/pulumi-aws/sdk/v7 v7.28.0/go.mod h1:MvfGxMurVnahZ4UtHSxvjuoytba7IsojtbsplqlXhdg= github.com/pulumi/pulumi-awsx/sdk/v3 v3.5.0 h1:4yNWM2R0VrF7nG2D6BjBkrxZcR2XHz3M/tYUwOS/5OY= github.com/pulumi/pulumi-awsx/sdk/v3 v3.5.0/go.mod h1:2/RMtCM6nOYsWHV0rFZRze7PdSMIKM61ZHbDGEwMaOs= github.com/pulumi/pulumi-azure-native-sdk/authorization/v3 v3.17.0 h1:XQ4akM+v4jT6bUDrbzqty0YpwPJAbS/47QzfuAt6+MM= @@ -375,8 +393,8 @@ github.com/pulumi/pulumi-random/sdk/v4 v4.19.2 h1:YDGarxRPtAgpnUg7nXVe+gVfVABBjo github.com/pulumi/pulumi-random/sdk/v4 v4.19.2/go.mod h1:Dyyj49M9eX2ct1b3maqDGikMPVCNxXthG0KAhhj7nmI= github.com/pulumi/pulumi-tls/sdk/v5 v5.3.1 h1:qy6N1fKNNCH2ylIm+v0i4VWAHGMPVNnAaOTffzxSda8= github.com/pulumi/pulumi-tls/sdk/v5 v5.3.1/go.mod h1:HyK4UFDdneYjFKP02pa6Hk1CE0Af4eTWkhbw5gF7wkU= -github.com/pulumi/pulumi/sdk/v3 v3.232.0 h1:pU9j5qYHYtYZGaIKha1KFuB9ggp2obcMD1U523tpEnk= -github.com/pulumi/pulumi/sdk/v3 v3.232.0/go.mod h1:33NoTpvQXlTtAuaPbompgZNA3Ye4XEvxNydELFlWza8= +github.com/pulumi/pulumi/sdk/v3 v3.234.0 h1:PoXVM2lJoyqavwPQlVQC6KzhGKNOJpz9OFxyojm8RjA= +github.com/pulumi/pulumi/sdk/v3 v3.234.0/go.mod h1:Eu9QVad1cSPymhTboINPqK6WZMaW7I0NHQcWOmxLYek= github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= @@ -439,8 +457,8 @@ github.com/zclconf/go-cty v1.18.1 h1:yEGE8M4iIZlyKQURZNb2SnEyZlZHUcBCnx6KF81KuwM github.com/zclconf/go-cty v1.18.1/go.mod h1:qpnV6EDNgC1sns/AleL1fvatHw72j+S+nS+MJ+T2CSg= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= -go.opentelemetry.io/collector/featuregate v1.56.0 h1:NjcbOZkdCSXddAJmFLdO+pv1gmAgrU6sC5PBga2KlKI= -go.opentelemetry.io/collector/featuregate v1.56.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= +go.opentelemetry.io/collector/featuregate v1.57.0 h1:KPDSUKYn6MHwgyGRSGPPcW/G96HH93pxuvvPwM+R8nY= +go.opentelemetry.io/collector/featuregate v1.57.0/go.mod h1:4ga1QBMPEejXXmpyJS8lmaRpknJ3Lb9Bvk6e420bUFU= go.opentelemetry.io/collector/internal/testutil v0.150.0 h1:J4PLQGPfbLVaL5eI1aMc0m0TMixV9wzBhNhoHU00J0I= go.opentelemetry.io/collector/internal/testutil v0.150.0/go.mod h1:Jkjs6rkqs973LqgZ0Fe3zrokQRKULYXPIf4HuqStiEE= go.opentelemetry.io/collector/pdata v1.56.0 h1:W+QAfN2Iz8SNss1T5JNzRWFnw+7oP1vXBQH9ZuOJkXY= @@ -548,12 +566,12 @@ golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gonum.org/v1/gonum v0.17.0 h1:VbpOemQlsSMrYmn7T2OUvQ4dqxQXU+ouZFQsZOx50z4= gonum.org/v1/gonum v0.17.0/go.mod h1:El3tOrEuMpv2UdMrbNlKEh9vd86bmQ6vqIcDwxEOc1E= -google.golang.org/genproto/googleapis/api v0.0.0-20260420184626-e10c466a9529 h1:zUWMZsvo/IJcD1t6MNCPO/azZTwz0TvwCBqr5aifoVY= -google.golang.org/genproto/googleapis/api v0.0.0-20260420184626-e10c466a9529/go.mod h1:a5OGAgyRr4lqco7AG9hQM9Fwh0N2ZV4grR0eXFEsXQg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529 h1:XF8+t6QQiS0o9ArVan/HW8Q7cycNPGsJf6GA2nXxYAg= -google.golang.org/genproto/googleapis/rpc v0.0.0-20260420184626-e10c466a9529/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.80.0 h1:Xr6m2WmWZLETvUNvIUmeD5OAagMw3FiKmMlTdViWsHM= -google.golang.org/grpc v1.80.0/go.mod h1:ho/dLnxwi3EDJA4Zghp7k2Ec1+c2jqup0bFkw07bwF4= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348 h1:U8orV30l6KpDsi9dxU0CoJZGbjS8EEpw+6ba+XwGPQA= +google.golang.org/genproto/googleapis/api v0.0.0-20260504160031-60b97b32f348/go.mod h1:Yzdzr5OOZFgSsEV2D/Xi9NL3bszpXFAg0hFJiRohcD8= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348 h1:pfIbyB44sWzHiCpRqIen67ZQnVXSfIxWrqUMk1qwODE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20260504160031-60b97b32f348/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= +google.golang.org/grpc v1.81.0 h1:W3G9N3KQf3BU+YuCtGKJk0CmxQNbAISICD/9AORxLIw= +google.golang.org/grpc v1.81.0/go.mod h1:xGH9GfzOyMTGIOXBJmXt+BX/V0kcdQbdcuwQ/zNw42I= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -581,14 +599,14 @@ k8s.io/client-go v0.35.4 h1:DN6fyaGuzK64UvnKO5fOA6ymSjvfGAnCAHAR0C66kD8= k8s.io/client-go v0.35.4/go.mod h1:2Pg9WpsS4NeOpoYTfHHfMxBG8zFMSAUi4O/qoiJC3nY= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-openapi v0.0.0-20260414162039-ec9c827d403f h1:4Qiq0YAoQATdgmHALJWz9rJ4fj20pB3xebpB4CFNhYM= -k8s.io/kube-openapi v0.0.0-20260414162039-ec9c827d403f/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= +k8s.io/kube-openapi v0.0.0-20260504175024-7bfe71ffdc10 h1:WTqpjlNkK8rfPghVhuBPxEswk9Y99sUpiMAfOClcuNM= +k8s.io/kube-openapi v0.0.0-20260504175024-7bfe71ffdc10/go.mod h1:Cyq7UE0QtGe+Zo+/6XFrxiS4Mq0tLyQEONkFzSkfp9o= k8s.io/utils v0.0.0-20260319190234-28399d86e0b5 h1:kBawHLSnx/mYHmRnNUf9d4CpjREbeZuxoSGOX/J+aYM= k8s.io/utils v0.0.0-20260319190234-28399d86e0b5/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= lukechampine.com/frand v1.5.1 h1:fg0eRtdmGFIxhP5zQJzM1lFDbD6CUfu/f+7WgAZd5/w= lukechampine.com/frand v1.5.1/go.mod h1:4VstaWc2plN4Mjr10chUD46RAVGWhpkZ5Nja8+Azp0Q= -pgregory.net/rapid v1.1.0 h1:CMa0sjHSru3puNx+J0MIAuiiEV4N0qj8/cMWGBBCsjw= -pgregory.net/rapid v1.1.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= +pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= +pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= diff --git a/oci/Containerfile b/oci/Containerfile index 57c98660a..c4de64590 100644 --- a/oci/Containerfile +++ b/oci/Containerfile @@ -1,12 +1,12 @@ -FROM registry.access.redhat.com/ubi9/go-toolset@sha256:35f08031de19eb51d6b35ed62c6357d3529bc69a8db65cf623ea5f0b44051999 as builder +FROM registry.access.redhat.com/ubi9/go-toolset@sha256:59ec4752cf86f0d0dd240b9e29c64d6ee560c28fc986171e126db1db216a246a as builder ARG TARGETARCH USER root WORKDIR /workspace COPY . . # renovate: datasource=github-releases depName=pulumi/pulumi -ENV PULUMI_VERSION 3.232.0 +ENV PULUMI_VERSION 3.234.0 ENV PULUMI_BASE_URL="https://github.com/pulumi/pulumi/releases/download/v${PULUMI_VERSION}/pulumi-v${PULUMI_VERSION}" ENV PULUMI_URL="${PULUMI_BASE_URL}-linux-x64.tar.gz" @@ -19,7 +19,7 @@ RUN unset VERSION \ && tar -xzvf pulumicli.tar.gz # ubi 9.5-1732804088 -FROM registry.access.redhat.com/ubi9/ubi@sha256:fd3612ebe7968002122fb8c41df2cf9bd3f9916c573f7248113cdec1d6f4c245 +FROM registry.access.redhat.com/ubi9/ubi@sha256:38952545b5a9ddf145152f37b0da702d7d75fac1ddc52c5e14b03c7a77c51586 ARG TARGETARCH LABEL org.opencontainers.image.authors="Redhat Developer" @@ -32,7 +32,7 @@ ENV AWS_SDK_LOAD_CONFIG=1 \ # Pulumi plugins # renovate: datasource=github-releases depName=pulumi/pulumi-aws -ARG PULUMI_AWS_VERSION=v7.27.0 +ARG PULUMI_AWS_VERSION=v7.28.0 # renovate: datasource=github-releases depName=pulumi/pulumi-awsx ARG PULUMI_AWSX_VERSION=v3.5.0 # renovate: datasource=github-releases depName=pulumi/pulumi-azure-native @@ -44,7 +44,7 @@ ARG PULUMI_TLS_VERSION=v5.3.1 # renovate: datasource=github-releases depName=pulumi/pulumi-random ARG PULUMI_RANDOM_VERSION=v4.19.2 # renovate: datasource=github-releases depName=pulumi/pulumi-aws-native -ARG PULUMI_AWS_NATIVE_VERSION=v1.62.0 +ARG PULUMI_AWS_NATIVE_VERSION=v1.63.0 # renovate: datasource=github-releases depName=pulumi/pulumi-gitlab ARG PULUMI_GITLAB_VERSION=v9.11.0 diff --git a/tools/go.mod b/tools/go.mod index cbf513586..c18b6a4bb 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -8,19 +8,24 @@ replace ( github.com/charmbracelet/lipgloss/v2 => charm.land/lipgloss/v2 v2.0.3 ) -require github.com/golangci/golangci-lint/v2 v2.11.4 +require github.com/golangci/golangci-lint/v2 v2.12.1 -require ( - github.com/charmbracelet/x/cellbuf v0.0.15 // indirect - github.com/golangci/golines v0.15.0 // indirect -) +require github.com/golangci/golines v0.15.0 // indirect require ( - github.com/bombsimon/wsl/v5 v5.7.0 // indirect + charm.land/lipgloss/v2 v2.0.3 // indirect + github.com/ClickHouse/clickhouse-go-linter v1.2.0 // indirect + github.com/bombsimon/wsl/v5 v5.8.0 // indirect + github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 // indirect + github.com/charmbracelet/x/termios v0.1.1 // indirect + github.com/charmbracelet/x/windows v0.2.2 // indirect github.com/clipperhouse/displaywidth v0.11.0 // indirect github.com/denis-tingaikin/go-header v0.5.0 // indirect github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d // indirect - go-simpler.org/sloglint v0.11.1 // indirect + github.com/golangci/rowserrcheck v0.0.0-20260419091836-c5f79b8a11ba // indirect + github.com/muesli/cancelreader v0.2.2 // indirect + github.com/ryancurrah/gomodguard/v2 v2.1.0 // indirect + go-simpler.org/sloglint v0.12.0 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect ) @@ -32,7 +37,6 @@ require ( github.com/alexkohler/prealloc v1.1.0 // indirect github.com/alfatraining/structtag v1.0.0 // indirect github.com/bombsimon/wsl/v4 v4.7.0 // indirect - github.com/charmbracelet/lipgloss v1.1.0 // indirect github.com/clipperhouse/uax29/v2 v2.7.0 // indirect github.com/godoc-lint/godoc-lint v0.11.2 // indirect github.com/golangci/asciicheck v0.5.0 // indirect @@ -55,9 +59,9 @@ require ( github.com/Antonboom/testifylint v1.6.4 // indirect github.com/BurntSushi/toml v1.6.0 // indirect github.com/Djarvur/go-err113 v0.1.1 // indirect - github.com/Masterminds/semver/v3 v3.4.0 // indirect + github.com/Masterminds/semver/v3 v3.5.0 // indirect github.com/OpenPeeDeeP/depguard/v2 v2.2.1 // indirect - github.com/alecthomas/chroma/v2 v2.23.1 // indirect + github.com/alecthomas/chroma/v2 v2.24.1 // indirect github.com/alecthomas/go-check-sumtype v0.3.1 // indirect github.com/alexkohler/nakedret/v2 v2.0.6 // indirect // github.com/alexkohler/prealloc v1.1.0 // indirect @@ -65,7 +69,6 @@ require ( github.com/alingse/nilnesserr v0.2.0 // indirect github.com/ashanbrown/forbidigo/v2 v2.3.1 // indirect github.com/ashanbrown/makezero/v2 v2.2.1 // indirect - github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bkielbasa/cyclop v1.2.3 // indirect github.com/blizzy78/varnamelen v0.8.0 // indirect @@ -91,7 +94,7 @@ require ( github.com/fatih/color v1.19.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.6 // indirect - github.com/fsnotify/fsnotify v1.9.0 // indirect + github.com/fsnotify/fsnotify v1.10.1 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/ghostiam/protogetter v0.3.20 // indirect github.com/go-critic/go-critic v0.14.3 // indirect @@ -125,7 +128,6 @@ require ( github.com/hexops/gotextdiff v1.0.3 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jgautheron/goconst v1.10.0 // indirect - github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jjti/go-spancheck v0.6.5 // indirect github.com/julz/importas v0.2.0 // indirect github.com/karamaru-alpha/copyloopvar v1.2.2 // indirect @@ -154,7 +156,6 @@ require ( github.com/mgechev/revive v1.15.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/moricho/tparallel v0.3.2 // indirect - github.com/muesli/termenv v0.16.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nishanths/exhaustive v0.12.0 // indirect @@ -180,7 +181,7 @@ require ( github.com/santhosh-tekuri/jsonschema/v6 v6.0.2 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect github.com/sashamelentyev/usestdlibvars v1.29.0 // indirect - github.com/securego/gosec/v2 v2.25.0 // indirect + github.com/securego/gosec/v2 v2.26.1 // indirect github.com/sirupsen/logrus v1.9.4 // indirect github.com/sivchari/containedctx v1.0.3 // indirect github.com/sonatard/noctx v0.5.1 // indirect @@ -214,7 +215,7 @@ require ( go.augendre.info/arangolint v0.4.0 // indirect go.augendre.info/fatcontext v0.9.0 // indirect go.uber.org/multierr v1.11.0 // indirect - go.uber.org/zap v1.27.1 // indirect + go.uber.org/zap v1.28.0 // indirect golang.org/x/exp/typeparams v0.0.0-20260410095643-746e56fc9e2f // indirect golang.org/x/mod v0.35.0 // indirect golang.org/x/sync v0.20.0 // indirect @@ -224,6 +225,6 @@ require ( google.golang.org/protobuf v1.36.11 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.7.0 // indirect - mvdan.cc/gofumpt v0.9.2 // indirect + mvdan.cc/gofumpt v0.10.0 // indirect mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 // indirect ) diff --git a/tools/go.sum b/tools/go.sum index 56bf53957..5650e11cd 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -2,6 +2,8 @@ 4d63.com/gocheckcompilerdirectives v1.3.0/go.mod h1:ofsJ4zx2QAuIP/NO/NAh1ig6R1Fb18/GI7RVMwz7kAY= 4d63.com/gochecknoglobals v0.2.2 h1:H1vdnwnMaZdQW/N+NrkT1SZMTBmcwHe9Vq8lJcYYTtU= 4d63.com/gochecknoglobals v0.2.2/go.mod h1:lLxwTQjL5eIesRbvnzIP3jZtG140FnTdz+AlMa+ogt0= +charm.land/lipgloss/v2 v2.0.3 h1:yM2zJ4Cf5Y51b7RHIwioil4ApI/aypFXXVHSwlM6RzU= +charm.land/lipgloss/v2 v2.0.3/go.mod h1:7myLU9iG/3xluAWzpY/fSxYYHCgoKTie7laxk6ATwXA= codeberg.org/chavacava/garif v0.2.1 h1:K9oYxSlvlXrHXyW26Z4q61bTpJDo1wbvXcYKar/F/LM= codeberg.org/chavacava/garif v0.2.1/go.mod h1:oHnDSmc0f9K1MeE+MQD/yjkiIB5Xsn5y3S9Dg96Xk84= codeberg.org/polyfloyd/go-errorlint v1.9.0 h1:VkdEEmA1VBpH6ecQoMR4LdphVI3fA4RrCh2an7YmodI= @@ -26,18 +28,20 @@ github.com/Antonboom/testifylint v1.6.4 h1:gs9fUEy+egzxkEbq9P4cpcMB6/G0DYdMeiFS8 github.com/Antonboom/testifylint v1.6.4/go.mod h1:YO33FROXX2OoUfwjz8g+gUxQXio5i9qpVy7nXGbxDD4= github.com/BurntSushi/toml v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk= github.com/BurntSushi/toml v1.6.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/ClickHouse/clickhouse-go-linter v1.2.0 h1:zbm174up3hTKjp0wKZVnTzRiG7tSF5XZF0FJG/MuCBI= +github.com/ClickHouse/clickhouse-go-linter v1.2.0/go.mod h1:pLorS7ffPTfuUV9M0SJgfHA/h/WQPQUk2FWG9x74cQ4= github.com/Djarvur/go-err113 v0.1.1 h1:eHfopDqXRwAi+YmCUas75ZE0+hoBHJ2GQNLYRSxao4g= github.com/Djarvur/go-err113 v0.1.1/go.mod h1:IaWJdYFLg76t2ihfflPZnM1LIQszWOsFDh2hhhAVF6k= -github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0= -github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE= +github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= github.com/MirrexOne/unqueryvet v1.5.4 h1:38QOxShO7JmMWT+eCdDMbcUgGCOeJphVkzzRgyLJgsQ= github.com/MirrexOne/unqueryvet v1.5.4/go.mod h1:fs9Zq6eh1LRIhsDIsxf9PONVUjYdFHdtkHIgZdJnyPU= github.com/OpenPeeDeeP/depguard/v2 v2.2.1 h1:vckeWVESWp6Qog7UZSARNqfu/cZqvki8zsuj3piCMx4= github.com/OpenPeeDeeP/depguard/v2 v2.2.1/go.mod h1:q4DKzC4UcVaAvcfd41CZh0PWpGgzrVxUYBlgKNGquUo= github.com/alecthomas/assert/v2 v2.11.0 h1:2Q9r3ki8+JYXvGsDyBXwH3LcJ+WK5D0gc5E8vS6K3D0= github.com/alecthomas/assert/v2 v2.11.0/go.mod h1:Bze95FyfUr7x34QZrjL+XP+0qgp/zg8yS+TtBj1WA3k= -github.com/alecthomas/chroma/v2 v2.23.1 h1:nv2AVZdTyClGbVQkIzlDm/rnhk1E9bU9nXwmZ/Vk/iY= -github.com/alecthomas/chroma/v2 v2.23.1/go.mod h1:NqVhfBR0lte5Ouh3DcthuUCTUpDC9cxBOfyMbMQPs3o= +github.com/alecthomas/chroma/v2 v2.24.1 h1:m5ffpfZbIb++k8AqFEKy9uVgY12xIQtBsQlc6DfZJQM= +github.com/alecthomas/chroma/v2 v2.24.1/go.mod h1:l+ohZ9xRXIbGe7cIW+YZgOGbvuVLjMps/FYN/CwuabI= github.com/alecthomas/go-check-sumtype v0.3.1 h1:u9aUvbGINJxLVXiFvHUlPEaD7VDULsrxJb4Aq31NLkU= github.com/alecthomas/go-check-sumtype v0.3.1/go.mod h1:A8TSiN3UPRw3laIgWEUOHHLPa6/r9MtoigdlP5h3K/E= github.com/alecthomas/repr v0.5.2 h1:SU73FTI9D1P5UNtvseffFSGmdNci/O6RsqzeXJtP0Qs= @@ -56,8 +60,6 @@ github.com/ashanbrown/forbidigo/v2 v2.3.1 h1:KAZijvQ7zeIBKbhikT4jCm0TLYXC4u78bTi github.com/ashanbrown/forbidigo/v2 v2.3.1/go.mod h1:2QDkLTzU6TV937eFROamXrW92M3paehdae4HCDCOZCM= github.com/ashanbrown/makezero/v2 v2.2.1 h1:A7uU8dgB1PA9aelTxHMfHIQ8Qev8AB3JLxJUBUsejqM= github.com/ashanbrown/makezero/v2 v2.2.1/go.mod h1:aEGT/9q3S8DHeE57C88z2a6xydvgx8J5hgXIGWgo0MY= -github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= -github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bkielbasa/cyclop v1.2.3 h1:faIVMIGDIANuGPWH031CZJTi2ymOQBULs9H21HSMa5w= @@ -66,8 +68,8 @@ github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= github.com/bombsimon/wsl/v4 v4.7.0 h1:1Ilm9JBPRczjyUs6hvOPKvd7VL1Q++PL8M0SXBDf+jQ= github.com/bombsimon/wsl/v4 v4.7.0/go.mod h1:uV/+6BkffuzSAVYD+yGyld1AChO7/EuLrCF/8xTiapg= -github.com/bombsimon/wsl/v5 v5.7.0 h1:mIAmJm1wwNCt6ZvSLh8wrlDAYfTVH6doKjG0TZgbNKk= -github.com/bombsimon/wsl/v5 v5.7.0/go.mod h1:w6GRulXihJQKElcdEZbO3VDt23/KIfdRFBaTAAec0Lk= +github.com/bombsimon/wsl/v5 v5.8.0 h1:JTkyfs4yl8SPejrCF2GdABXE+mO1WvM7iUYzRWlsxDs= +github.com/bombsimon/wsl/v5 v5.8.0/go.mod h1:AbOLsulgkqP4ZnitHf9gwPtCOGlrzkk0jb0uNxRSY0o= github.com/breml/bidichk v0.3.3 h1:WSM67ztRusf1sMoqH6/c4OBCUlRVTKq+CbSeo0R17sE= github.com/breml/bidichk v0.3.3/go.mod h1:ISbsut8OnjB367j5NseXEGGgO/th206dVa427kR8YTE= github.com/breml/errchkjson v0.4.1 h1:keFSS8D7A2T0haP9kzZTi7o26r7kE3vymjZNeNDRDwg= @@ -86,14 +88,16 @@ github.com/charithe/durationcheck v0.0.11 h1:g1/EX1eIiKS57NTWsYtHDZ/APfeXKhye1Di github.com/charithe/durationcheck v0.0.11/go.mod h1:x5iZaixRNl8ctbM+3B2RrPG5t856TxRyVQEnbIEM2X4= github.com/charmbracelet/colorprofile v0.4.3 h1:QPa1IWkYI+AOB+fE+mg/5/4HRMZcaXex9t5KX76i20Q= github.com/charmbracelet/colorprofile v0.4.3/go.mod h1:/zT4BhpD5aGFpqQQqw7a+VtHCzu+zrQtt1zhMt9mR4Q= -github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= -github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318 h1:OqDqxQZliC7C8adA7KjelW3OjtAxREfeHkNcd66wpeI= +github.com/charmbracelet/ultraviolet v0.0.0-20251205161215-1948445e3318/go.mod h1:Y6kE2GzHfkyQQVCSL9r2hwokSrIlHGzZG+71+wDYSZI= github.com/charmbracelet/x/ansi v0.11.7 h1:kzv1kJvjg2S3r9KHo8hDdHFQLEqn4RBCb39dAYC84jI= github.com/charmbracelet/x/ansi v0.11.7/go.mod h1:9qGpnAVYz+8ACONkZBUWPtL7lulP9No6p1epAihUZwQ= -github.com/charmbracelet/x/cellbuf v0.0.15 h1:ur3pZy0o6z/R7EylET877CBxaiE1Sp1GMxoFPAIztPI= -github.com/charmbracelet/x/cellbuf v0.0.15/go.mod h1:J1YVbR7MUuEGIFPCaaZ96KDl5NoS0DAWkskup+mOY+Q= github.com/charmbracelet/x/term v0.2.2 h1:xVRT/S2ZcKdhhOuSP4t5cLi5o+JxklsoEObBSgfgZRk= github.com/charmbracelet/x/term v0.2.2/go.mod h1:kF8CY5RddLWrsgVwpw4kAa6TESp6EB5y3uxGLeCqzAI= +github.com/charmbracelet/x/termios v0.1.1 h1:o3Q2bT8eqzGnGPOYheoYS8eEleT5ZVNYNy8JawjaNZY= +github.com/charmbracelet/x/termios v0.1.1/go.mod h1:rB7fnv1TgOPOyyKRJ9o+AsTU/vK5WHJ2ivHeut/Pcwo= +github.com/charmbracelet/x/windows v0.2.2 h1:IofanmuvaxnKHuV04sC0eBy/smG6kIKrWG2/jYn2GuM= +github.com/charmbracelet/x/windows v0.2.2/go.mod h1:/8XtdKZzedat74NQFn0NGlGL4soHB0YQZrETF96h75k= github.com/ckaznocha/intrange v0.3.1 h1:j1onQyXvHUsPWujDH6WIjhyH26gkRt/txNlV7LspvJs= github.com/ckaznocha/intrange v0.3.1/go.mod h1:QVepyz1AkUoFQkpEqksSYpNpUo3c5W7nWh/s6SHIJJk= github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8= @@ -126,8 +130,8 @@ github.com/firefart/nonamedreturns v1.0.6 h1:vmiBcKV/3EqKY3ZiPxCINmpS431OcE1S47A github.com/firefart/nonamedreturns v1.0.6/go.mod h1:R8NisJnSIpvPWheCq0mNRXJok6D8h7fagJTF8EMEwCo= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= -github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k= -github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0= +github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= +github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= github.com/ghostiam/protogetter v0.3.20 h1:oW7OPFit2FxZOpmMRPP9FffU4uUpfeE/rEdE1f+MzD0= @@ -136,8 +140,8 @@ github.com/go-critic/go-critic v0.14.3 h1:5R1qH2iFeo4I/RJU8vTezdqs08Egi4u5p6vOES github.com/go-critic/go-critic v0.14.3/go.mod h1:xwntfW6SYAd7h1OqDzmN6hBX/JxsEKl5up/Y2bsxgVQ= github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= -github.com/go-quicktest/qt v1.101.0/go.mod h1:14Bz/f7NwaXPtdYEgzsx46kqSxVwTbzVZsDC26tQJow= +github.com/go-quicktest/qt v1.102.0 h1:HSQxCeh5YZH3EL3W39ixjtyaEhcWSXQHtHnMBzSs474= +github.com/go-quicktest/qt v1.102.0/go.mod h1:p4lGIVX+8Wa6ZPNDvqcxq36XpUDLh42FLetFU7odllI= github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= @@ -177,8 +181,8 @@ github.com/golangci/go-printf-func-name v0.1.1 h1:hIYTFJqAGp1iwoIfsNTpoq1xZAarog github.com/golangci/go-printf-func-name v0.1.1/go.mod h1:Es64MpWEZbh0UBtTAICOZiB+miW53w/K9Or/4QogJss= github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d h1:viFft9sS/dxoYY0aiOTsLKO2aZQAPT4nlQCsimGcSGE= github.com/golangci/gofmt v0.0.0-20250106114630-d62b90e6713d/go.mod h1:ivJ9QDg0XucIkmwhzCDsqcnxxlDStoTl89jDMIoNxKY= -github.com/golangci/golangci-lint/v2 v2.11.4 h1:GK+UlZBN5y7rh2PBnHA93XLSX6RaF7uhzJQ3JwU1wuA= -github.com/golangci/golangci-lint/v2 v2.11.4/go.mod h1:ODQDCASMA3VqfZYIbbQLpTRTzV7O/vjmIRF6u8NyFwI= +github.com/golangci/golangci-lint/v2 v2.12.1 h1:Rr07Ps/u+kvQqSO4L026WOSVvOlMU+RZTa/lossFaJA= +github.com/golangci/golangci-lint/v2 v2.12.1/go.mod h1:e/wBh0xvA13ag/OWByUmvjc9oYPtcKGpXycldJbc7t0= github.com/golangci/golines v0.15.0 h1:Qnph25g8Y1c5fdo1X7GaRDGgnMHgnxh4Gk4VfPTtRx0= github.com/golangci/golines v0.15.0/go.mod h1:AZjXd23tbHMpowhtnGlj9KCNsysj72aeZVVHnVcZx10= github.com/golangci/misspell v0.8.0 h1:qvxQhiE2/5z+BVRo1kwYA8yGz+lOlu5Jfvtx2b04Jbg= @@ -187,6 +191,8 @@ github.com/golangci/plugin-module-register v0.1.2 h1:e5WM6PO6NIAEcij3B053CohVp3H github.com/golangci/plugin-module-register v0.1.2/go.mod h1:1+QGTsKBvAIvPvoY/os+G5eoqxWn70HYDm2uvUyGuVw= github.com/golangci/revgrep v0.8.0 h1:EZBctwbVd0aMeRnNUsFogoyayvKHyxlV3CdUA46FX2s= github.com/golangci/revgrep v0.8.0/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k= +github.com/golangci/rowserrcheck v0.0.0-20260419091836-c5f79b8a11ba h1:lqtcnSMDuuJdu/LrKWi5RJzpSNLOJXYe/nzQutTI5kg= +github.com/golangci/rowserrcheck v0.0.0-20260419091836-c5f79b8a11ba/go.mod h1:sCBNcpRmhJCtbFGz49+IM3ETTFf7QdJ30AeYCd43NKk= github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e h1:ai0EfmVYE2bRA5htgAG9r7s3tHsfjIhN98WshBTJ9jM= github.com/golangci/swaggoswag v0.0.0-20250504205917-77f2aca3143e/go.mod h1:Vrn4B5oR9qRwM+f54koyeH3yzphlecwERs0el27Fr/s= github.com/golangci/unconvert v0.0.0-20250410112200-a129a6e6413e h1:gD6P7NEo7Eqtt0ssnqSJNNndxe69DOQ24A5h7+i3KpM= @@ -227,8 +233,6 @@ github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2 github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jgautheron/goconst v1.10.0 h1:Ptt+OoE4NaEWKhLrWrrN3IpZdGLiqaf7WLnEX/iv4Jw= github.com/jgautheron/goconst v1.10.0/go.mod h1:0p+wv1lFOiUr0IlNNT1nrm6+8DB8u2sU6KHGzFRXHDc= -github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= -github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jjti/go-spancheck v0.6.5 h1:lmi7pKxa37oKYIMScialXUK6hP3iY5F1gu+mLBPgYB8= github.com/jjti/go-spancheck v0.6.5/go.mod h1:aEogkeatBrbYsyW6y5TgDfihCulDYciL1B7rG2vSsrU= github.com/julz/importas v0.2.0 h1:y+MJN/UdL63QbFJHws9BVC5RpA2iq0kpjrFajTGivjQ= @@ -291,8 +295,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/moricho/tparallel v0.3.2 h1:odr8aZVFA3NZrNybggMkYO3rgPRcqjeQUlBBFVxKHTI= github.com/moricho/tparallel v0.3.2/go.mod h1:OQ+K3b4Ln3l2TZveGCywybl68glfLEwFGqvnjok8b+U= -github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= -github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= +github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA= +github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= @@ -303,8 +307,8 @@ github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= github.com/nunnatsa/ginkgolinter v0.23.0 h1:x3o4DGYOWbBMP/VdNQKgSj+25aJKx2Pe6lHr8gBcgf8= github.com/nunnatsa/ginkgolinter v0.23.0/go.mod h1:9qN1+0akwXEccwV1CAcCDfcoBlWXHB+ML9884pL4SZ4= -github.com/onsi/ginkgo/v2 v2.28.1 h1:S4hj+HbZp40fNKuLUQOYLDgZLwNUVn19N3Atb98NCyI= -github.com/onsi/ginkgo/v2 v2.28.1/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE= +github.com/onsi/ginkgo/v2 v2.28.2 h1:DTrMfpqxiNUyQ3Y0zhn1n3cOO2euFgQPYIpkWwxVFps= +github.com/onsi/ginkgo/v2 v2.28.2/go.mod h1:CLtbVInNckU3/+gC8LzkGUb9oF+e8W8TdUsxPwvdOgE= github.com/onsi/gomega v1.39.1 h1:1IJLAad4zjPn2PsnhH70V4DKRFlrCzGBNrNaru+Vf28= github.com/onsi/gomega v1.39.1/go.mod h1:hL6yVALoTOxeWudERyfppUcZXjMwIMLnuSfruD2lcfg= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= @@ -345,6 +349,8 @@ github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7 github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryancurrah/gomodguard v1.4.1 h1:eWC8eUMNZ/wM/PWuZBv7JxxqT5fiIKSIyTvjb7Elr+g= github.com/ryancurrah/gomodguard v1.4.1/go.mod h1:qnMJwV1hX9m+YJseXEBhd2s90+1Xn6x9dLz11ualI1I= +github.com/ryancurrah/gomodguard/v2 v2.1.0 h1:iIIARHe7Fsp10LY5utfMmYA++hkVuKsMFGDzxnVcijU= +github.com/ryancurrah/gomodguard/v2 v2.1.0/go.mod h1:ryDqr6as4otkNbUp/U0m7zAsxGpwcJ9NtL6mvy9Zzdw= github.com/ryanrolds/sqlclosecheck v0.6.0 h1:pEyL9okISdg1F1SEpJNlrEotkTGerv5BMk7U4AG0eVg= github.com/ryanrolds/sqlclosecheck v0.6.0/go.mod h1:xyX16hsDaCMXHrMJ3JMzGf5OpDfHTOTTQrT7HOFUmeU= github.com/sagikazarmark/locafero v0.12.0 h1:/NQhBAkUb4+fH1jivKHWusDYFjMOOKU88eegjfxfHb4= @@ -357,8 +363,8 @@ github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tM github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= github.com/sashamelentyev/usestdlibvars v1.29.0 h1:8J0MoRrw4/NAXtjQqTHrbW9NN+3iMf7Knkq057v4XOQ= github.com/sashamelentyev/usestdlibvars v1.29.0/go.mod h1:8PpnjHMk5VdeWlVb4wCdrB8PNbLqZ3wBZTZWkrpZZL8= -github.com/securego/gosec/v2 v2.25.0 h1:8fN1/16qO0aA3ktgU9nDW5PdrCPd4vgpgaPM8ZE+aEA= -github.com/securego/gosec/v2 v2.25.0/go.mod h1:JjqD2HhHtH1GQYb2r2iYdqBihiA3wo5be9BED8+Uv5c= +github.com/securego/gosec/v2 v2.26.1 h1:gdkttGhQFVehqRJ8grKH4DrpqM/QlPKNHBnl8QgcEC4= +github.com/securego/gosec/v2 v2.26.1/go.mod h1:57UW4p0uoP3kxoTkhoo3axLdVAi+OWrLg/Ax/kdqtPE= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= @@ -429,7 +435,6 @@ github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2 github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= @@ -438,8 +443,8 @@ go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= go-simpler.org/musttag v0.14.0 h1:XGySZATqQYSEV3/YTy+iX+aofbZZllJaqwFWs+RTtSo= go-simpler.org/musttag v0.14.0/go.mod h1:uP8EymctQjJ4Z1kUnjX0u2l60WfUdQxCwSNKzE1JEOE= -go-simpler.org/sloglint v0.11.1 h1:xRbPepLT/MHPTCA6TS/wNfZrDzkGvCCqUv4Bdwc3H7s= -go-simpler.org/sloglint v0.11.1/go.mod h1:2PowwiCOK8mjiF+0KGifVOT8ZsCNiFzvfyJeJOIt8MQ= +go-simpler.org/sloglint v0.12.0 h1:UzWDlLWNE5FLqsvyq3tWYHuQMbqrervOhT8qPl4Mmw4= +go-simpler.org/sloglint v0.12.0/go.mod h1:jBjjC2bm8rYrs88oTRlFX497kWjJsyZWYoNaXkGRI6I= go.augendre.info/arangolint v0.4.0 h1:xSCZjRoS93nXazBSg5d0OGCi9APPLNMmmLrC995tR50= go.augendre.info/arangolint v0.4.0/go.mod h1:l+f/b4plABuFISuKnTGD4RioXiCCgghv2xqst/xOvAA= go.augendre.info/fatcontext v0.9.0 h1:Gt5jGD4Zcj8CDMVzjOJITlSb9cEch54hjRRlN3qDojE= @@ -448,8 +453,8 @@ go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc= -go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.3 h1:6gvOSjQoTB3vt1l+CU+tSyi/HOjfOjRLJ4YwYZGwRO0= go.yaml.in/yaml/v2 v2.4.3/go.mod h1:zSxWcmIDjOzPXpjlTTbAsKokqkDNAVtZO0WOMiT90s8= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -467,7 +472,6 @@ golang.org/x/exp/typeparams v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:PqrXSW6 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= @@ -479,7 +483,6 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= @@ -500,9 +503,7 @@ golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -528,7 +529,6 @@ golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= @@ -552,7 +552,7 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU= honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc= -mvdan.cc/gofumpt v0.9.2 h1:zsEMWL8SVKGHNztrx6uZrXdp7AX8r421Vvp23sz7ik4= -mvdan.cc/gofumpt v0.9.2/go.mod h1:iB7Hn+ai8lPvofHd9ZFGVg2GOr8sBUw1QUWjNbmIL/s= +mvdan.cc/gofumpt v0.10.0 h1:yGGpRS2pBN2OQIi7b21IXknJna7faPkFaVfHLrN6Euo= +mvdan.cc/gofumpt v0.10.0/go.mod h1:sU2ElXHzOEmvoPqfutYG7uunlueR4K2T1JFml40SzP4= mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15 h1:ssMzja7PDPJV8FStj7hq9IKiuiKhgz9ErWw+m68e7DI= mvdan.cc/unparam v0.0.0-20251027182757-5beb8c8f8f15/go.mod h1:4M5MMXl2kW6fivUT6yRGpLLPNfuGtU2Z0cPvFquGDYU= diff --git a/tools/vendor/charm.land/lipgloss/v2/.editorconfig b/tools/vendor/charm.land/lipgloss/v2/.editorconfig new file mode 100644 index 000000000..5de2df8c5 --- /dev/null +++ b/tools/vendor/charm.land/lipgloss/v2/.editorconfig @@ -0,0 +1,18 @@ +# https://editorconfig.org/ + +root = true + +[*] +charset = utf-8 +insert_final_newline = true +trim_trailing_whitespace = true +indent_style = space +indent_size = 2 + +[*.go] +indent_style = tab +indent_size = 8 + +[*.golden] +insert_final_newline = false +trim_trailing_whitespace = false diff --git a/tools/vendor/charm.land/lipgloss/v2/.gitattributes b/tools/vendor/charm.land/lipgloss/v2/.gitattributes new file mode 100644 index 000000000..d5273520a --- /dev/null +++ b/tools/vendor/charm.land/lipgloss/v2/.gitattributes @@ -0,0 +1 @@ +*.golden linguist-generated=true -text diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/.gitignore b/tools/vendor/charm.land/lipgloss/v2/.gitignore similarity index 53% rename from tools/vendor/github.com/charmbracelet/lipgloss/.gitignore rename to tools/vendor/charm.land/lipgloss/v2/.gitignore index db482015d..3b478f575 100644 --- a/tools/vendor/github.com/charmbracelet/lipgloss/.gitignore +++ b/tools/vendor/charm.land/lipgloss/v2/.gitignore @@ -1,2 +1,3 @@ ssh_example_ed25519* -dist/ +/tmp +**/.crush/** diff --git a/tools/vendor/charm.land/lipgloss/v2/.golangci.yml b/tools/vendor/charm.land/lipgloss/v2/.golangci.yml new file mode 100644 index 000000000..c90f03161 --- /dev/null +++ b/tools/vendor/charm.land/lipgloss/v2/.golangci.yml @@ -0,0 +1,47 @@ +version: "2" +run: + tests: false +linters: + enable: + - bodyclose + - exhaustive + - goconst + - godot + - gomoddirectives + - goprintffuncname + - gosec + - misspell + - nakedret + - nestif + - nilerr + - noctx + - nolintlint + - prealloc + - revive + - rowserrcheck + - sqlclosecheck + - tparallel + - unconvert + - unparam + - whitespace + - wrapcheck + exclusions: + rules: + - text: '(slog|log)\.\w+' + linters: + - noctx + generated: lax + presets: + - common-false-positives + settings: + exhaustive: + default-signifies-exhaustive: true +issues: + max-issues-per-linter: 0 + max-same-issues: 0 +formatters: + enable: + - gofumpt + - goimports + exclusions: + generated: lax diff --git a/tools/vendor/charm.land/lipgloss/v2/.goreleaser.yml b/tools/vendor/charm.land/lipgloss/v2/.goreleaser.yml new file mode 100644 index 000000000..c61970e07 --- /dev/null +++ b/tools/vendor/charm.land/lipgloss/v2/.goreleaser.yml @@ -0,0 +1,5 @@ +includes: + - from_url: + url: charmbracelet/meta/main/goreleaser-lib.yaml +# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json + diff --git a/tools/vendor/charm.land/lipgloss/v2/LICENSE b/tools/vendor/charm.land/lipgloss/v2/LICENSE new file mode 100644 index 000000000..9f60dc1fc --- /dev/null +++ b/tools/vendor/charm.land/lipgloss/v2/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2021-2026 Charmbracelet, Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/README.md b/tools/vendor/charm.land/lipgloss/v2/README.md similarity index 61% rename from tools/vendor/github.com/charmbracelet/lipgloss/README.md rename to tools/vendor/charm.land/lipgloss/v2/README.md index cee2371ce..4fda64003 100644 --- a/tools/vendor/github.com/charmbracelet/lipgloss/README.md +++ b/tools/vendor/charm.land/lipgloss/v2/README.md @@ -1,23 +1,21 @@ # Lip Gloss -
-Style definitions for nice terminal layouts. Built with TUIs in mind. +Style definitions for nice terminal layouts. Built with TUIs in mind.
- + Lip Gloss takes an expressive, declarative approach to terminal rendering. Users familiar with CSS will feel at home with Lip Gloss. ```go - -import "github.com/charmbracelet/lipgloss" +import "charm.land/lipgloss/v2" var style = lipgloss.NewStyle(). Bold(true). @@ -27,9 +25,20 @@ var style = lipgloss.NewStyle(). PaddingLeft(4). Width(22) -fmt.Println(style.Render("Hello, kitty")) +lipgloss.Println(style.Render("Hello, kitty")) +``` + +## Installation + +```bash +go get charm.land/lipgloss/v2 ``` +> [!TIP] +> +> Upgrading from v1? Check out the [upgrade guide](./UPGRADE_GUIDE_V2.md), or +> point your LLM at it and let it go to town. + ## Colors Lip Gloss supports the following color profiles: @@ -60,45 +69,58 @@ lipgloss.Color("#3C3C3C") // a dark gray ...as well as a 1-bit ASCII profile, which is black and white only. -The terminal's color profile will be automatically detected, and colors outside -the gamut of the current palette will be automatically coerced to their closest -available value. - -### Adaptive Colors - -You can also specify color options for light and dark backgrounds: +There are also named constants for the 16 standard ANSI colors: ```go -lipgloss.AdaptiveColor{Light: "236", Dark: "248"} +lipgloss.Black +lipgloss.Red +lipgloss.Green +lipgloss.Yellow +lipgloss.Blue +lipgloss.Magenta +lipgloss.Cyan +lipgloss.White +lipgloss.BrightBlack +lipgloss.BrightRed +lipgloss.BrightGreen +lipgloss.BrightYellow +lipgloss.BrightBlue +lipgloss.BrightMagenta +lipgloss.BrightCyan +lipgloss.BrightWhite ``` -The terminal's background color will automatically be detected and the -appropriate color will be chosen at runtime. +### Automatically Downsampling Colors -### Complete Colors +Some users don't have Truecolor terminals. Other times, output might not +support color at all (for example, in logs). Lip Gloss was designed to handle +this gracefully by automatically downsampling colors to the best available +profile. -CompleteColor specifies exact values for True Color, ANSI256, and ANSI color -profiles. +If you're using Lip Gloss with Bubble Tea, there’s nothing to do. If you're +using Lip Gloss standalone, just use `lipgloss.Println` or `lipgloss.Sprint` +(and their variants). -```go -lipgloss.CompleteColor{TrueColor: "#0000FF", ANSI256: "86", ANSI: "5"} -``` +For more, see [advanced color usage](#advanced-color-usage). -Automatic color degradation will not be performed in this case and it will be -based on the color specified. +### Color Utilities -### Complete Adaptive Colors - -You can use `CompleteColor` with `AdaptiveColor` to specify the exact values for -light and dark backgrounds without automatic color degradation. +Lip Gloss ships with a handful of handy tools for working with colors: ```go -lipgloss.CompleteAdaptiveColor{ - Light: CompleteColor{TrueColor: "#d7ffae", ANSI256: "193", ANSI: "11"}, - Dark: CompleteColor{TrueColor: "#d75fee", ANSI256: "163", ANSI: "5"}, -} +c := lipgloss.Color("#EB4268") // Sriracha sauce color +dark := lipgloss.Darken(c, 0.5) // dark Sriracha sauce +light := lipgloss.Lighten(c, 0.35) // light Sriracha sauce +green := lipgloss.Complementary(c) // greenish Sriracha sauce +withAlpha := lipgloss.Alpha(c, 0.2) // watered down Sriracha sauce ``` +### Advanced Color Tooling + +Lip Gloss also supports color blending, automatically choosing light or dark +variants of colors at runtime, and a lot more. For details, see [Advanced Color +Usage](#advanced-color-usage) and [the docs][docs]. + ## Inline Formatting Lip Gloss supports the usual ANSI text formatting options: @@ -114,6 +136,34 @@ var style = lipgloss.NewStyle(). Reverse(true) ``` +### Underline Styles + +Beyond simple on/off, underlines support multiple styles and custom colors: + +```go +s := lipgloss.NewStyle(). + UnderlineStyle(lipgloss.UnderlineCurly). + UnderlineColor(lipgloss.Color("#FF0000")) +``` + +Available styles: `UnderlineNone`, `UnderlineSingle`, `UnderlineDouble`, +`UnderlineCurly`, `UnderlineDotted`, `UnderlineDashed`. + +### Hyperlinks + +Styles can render clickable hyperlinks in supporting terminals: + +```go +s := lipgloss.NewStyle(). + Foreground(lipgloss.Color("#7B2FBE")). + Hyperlink("https://charm.land") + +lipgloss.Println(s.Render("Visit Charm")) +``` + +In unsupported terminals this will degrade gracefully and hyperlinks will +simply not render. + ## Block-Level Formatting Lip Gloss also supports rules for block-level formatting: @@ -152,6 +202,16 @@ lipgloss.NewStyle().Padding(1, 4, 2) lipgloss.NewStyle().Margin(2, 4, 3, 1) ``` +You can also customize the characters used for padding and margin fill: + +```go +s := lipgloss.NewStyle(). + Padding(1, 2). + PaddingChar('·'). + Margin(1, 2). + MarginChar('░') +``` + ## Aligning Text You can align paragraphs of text to the left, right, or center. @@ -221,7 +281,15 @@ lipgloss.NewStyle(). Border(lipgloss.DoubleBorder(), true, false, false, true) ``` -For more on borders see [the docs][docs]. +You can also pass multiple colors to a border for a gradient effect: + +```go +s := lipgloss.NewStyle(). + Border(lipgloss.RoundedBorder()). + BorderForegroundBlend(lipgloss.Color("#FF0000"), lipgloss.Color("#0000FF")) +``` + +For more on borders see [the docs](https://pkg.go.dev/charm.land/lipgloss/v2#Border). ## Copying Styles @@ -233,12 +301,10 @@ style := lipgloss.NewStyle().Foreground(lipgloss.Color("219")) copiedStyle := style // this is a true copy wildStyle := style.Blink(true) // this is also true copy, with blink added - ``` -Since `Style` data structures contains only primitive types, assigning a style -to another effectively creates a new copy of the style without mutating the -original. +Since `Style` is a pure value type, assigning a style to another effectively +creates a new copy of the style without mutating the original. ## Inheritance @@ -269,7 +335,7 @@ var style = lipgloss.NewStyle(). UnsetBackground() // never mind ``` -When a rule is unset, it won't be inherited or copied. +When a rule is unset, it won’t be inherited or copied. ## Enforcing Rules @@ -302,50 +368,57 @@ style = style.TabWidth(0) // remove tabs entirely style = style.TabWidth(lipgloss.NoTabConversion) // leave tabs intact ``` +## Wrapping + +The `Wrap` function wraps text while preserving ANSI styles and hyperlinks +across line boundaries: + +```go +wrapped := lipgloss.Wrap(styledText, 40, " ") +``` + ## Rendering Generally, you just call the `Render(string...)` method on a `lipgloss.Style`: ```go style := lipgloss.NewStyle().Bold(true).SetString("Hello,") -fmt.Println(style.Render("kitty.")) // Hello, kitty. -fmt.Println(style.Render("puppy.")) // Hello, puppy. +lipgloss.Println(style.Render("kitty.")) // Hello, kitty. +lipgloss.Println(style.Render("puppy.")) // Hello, puppy. ``` But you could also use the Stringer interface: ```go var style = lipgloss.NewStyle().SetString("你好,猫咪。").Bold(true) -fmt.Println(style) // 你好,猫咪。 +lipgloss.Println(style) // 你好,猫咪。 ``` -### Custom Renderers +## Utilities -Custom renderers allow you to render to a specific outputs. This is -particularly important when you want to render to different outputs and -correctly detect the color profile and dark background status for each, such as -in a server-client situation. +In addition to pure styling, Lip Gloss also ships with some utilities to help +assemble your layouts. -```go -func myLittleHandler(sess ssh.Session) { - // Create a renderer for the client. - renderer := lipgloss.NewRenderer(sess) +### Compositing - // Create a new style on the renderer. - style := renderer.NewStyle().Background(lipgloss.AdaptiveColor{Light: "63", Dark: "228"}) +@@ -564,7 +647,7 @@ itemStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("212")).MarginRight(1 l := list.New( "Glossier", - "Claire’s Boutique", + "Claire's Boutique", "Nyx", "Mac", "Milk", @@ -617,7 +700,7 @@ for i := 0; i < repeat; i++ { Lip Gloss ships with a tree rendering sub-package. ```go -import "github.com/charmbracelet/lipgloss/tree" +import "charm.land/lipgloss/v2/tree" ``` Define a new tree. @@ -630,7 +713,7 @@ t := tree.Root("."). Print the tree. ```go -fmt.Println(t) +lipgloss.Println(t) // . // ├── A @@ -661,7 +744,7 @@ t := tree.Root("."). Print the tree. ```go -fmt.Println(t) +lipgloss.Println(t) ```
@@ -713,49 +796,159 @@ for i := 0; i < repeat; i++ {
}
```
----
+## Advanced Color Usage
-## FAQ
+One of the most powerful features of Lip Gloss is the ability to render
+different colors at runtime depending on the user's terminal and environment,
+allowing you to present the best possible user experience.
- This is most likely due to your locale and encoding, particularly with
-regard to Chinese, Japanese, and Korean (for example, For details see https://github.com/charmbracelet/lipgloss/issues/40. Lip Gloss automatically degrades colors to the best available option in the
-given terminal, and if output's not a TTY it will remove color output entirely.
-This is common when running tests, CI, or when piping output elsewhere. If necessary, you can force a color profile in your tests with
-
-Why are things misaligning? Why are borders at the wrong widths?
-
-zh_CN.UTF-8
-or ja_JP.UTF-8). The most direct way to fix this is to set
-RUNEWIDTH_EASTASIAN=0 in your environment.
-Why isn't Lip Gloss displaying colors?
-
-Migrating from v1?
-SetColorProfile.
+
Charm热爱开源 • Charm loves open source
-[docs]: https://pkg.go.dev/github.com/charmbracelet/lipgloss?tab=doc
-[wish]: https://github.com/charmbracelet/wish
-[ssh-example]: examples/ssh
+[docs]: https://pkg.go.dev/charm.land/lipgloss/v2?tab=doc
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml b/tools/vendor/charm.land/lipgloss/v2/Taskfile.yaml
similarity index 72%
rename from tools/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml
rename to tools/vendor/charm.land/lipgloss/v2/Taskfile.yaml
index 0b4a7711a..84fcf6c66 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/Taskfile.yaml
+++ b/tools/vendor/charm.land/lipgloss/v2/Taskfile.yaml
@@ -1,6 +1,6 @@
# https://taskfile.dev
-version: '3'
+version: "3"
tasks:
lint:
@@ -17,3 +17,8 @@ tasks:
desc: Run table tests
cmds:
- go test ./table {{.CLI_ARGS}}
+
+ test:tree:
+ desc: Run tree tests
+ cmds:
+ - go test ./tree {{.CLI_ARGS}}
diff --git a/tools/vendor/charm.land/lipgloss/v2/UPGRADE_GUIDE_V2.md b/tools/vendor/charm.land/lipgloss/v2/UPGRADE_GUIDE_V2.md
new file mode 100644
index 000000000..8f123f19d
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/UPGRADE_GUIDE_V2.md
@@ -0,0 +1,504 @@
+# Lip Gloss v2 Upgrade Guide
+
+This guide covers migrating from Lip Gloss v1 (`github.com/charmbracelet/lipgloss`)
+to Lip Gloss v2 (`charm.land/lipgloss/v2`). It is written for both humans and
+LLMs performing automated migrations.
+
+---
+
+## Table of Contents
+
+1. [Quick Start](#quick-start)
+2. [Module Path](#module-path)
+3. [Color System](#color-system)
+4. [Renderer Removal](#renderer-removal)
+5. [Printing and Color Downsampling](#printing-and-color-downsampling)
+6. [Background Detection and Adaptive Colors](#background-detection-and-adaptive-colors)
+7. [Whitespace Options](#whitespace-options)
+8. [Underline](#underline)
+9. [Style API Changes](#style-api-changes)
+10. [Tree Subpackage](#tree-subpackage)
+11. [Removed APIs](#removed-apis)
+12. [Quick Reference Table](#quick-reference-table)
+
+---
+
+## Quick Start
+
+For the fastest possible upgrade, do these two things:
+
+### 1. Use the `compat` package for adaptive/complete colors
+
+```go
+import "charm.land/lipgloss/v2/compat"
+
+// v1
+color := lipgloss.AdaptiveColor{Light: "#f1f1f1", Dark: "#cccccc"}
+
+// v2
+color := compat.AdaptiveColor{Light: lipgloss.Color("#f1f1f1"), Dark: lipgloss.Color("#cccccc")}
+```
+
+The `compat` package reads `stdin`/`stdout` globally, just like v1. To
+customize:
+
+```go
+import (
+ "charm.land/lipgloss/v2/compat"
+ "github.com/charmbracelet/colorprofile"
+)
+
+func init() {
+ compat.HasDarkBackground = lipgloss.HasDarkBackground(os.Stdin, os.Stderr)
+ compat.Profile = colorprofile.Detect(os.Stderr, os.Environ())
+}
+```
+
+### 2. Use Lip Gloss writers for output
+
+```go
+// v1
+fmt.Println(s)
+
+// v2
+lipgloss.Println(s)
+```
+
+This ensures colors are automatically downsampled. If you're using Bubble Tea
+v2, this step is unnecessary — Bubble Tea handles it for you.
+
+**That's the quick path.** Read on for the full migration details.
+
+---
+
+## Module Path
+
+The import path has changed.
+
+```go
+// v1
+import "github.com/charmbracelet/lipgloss"
+
+// v2
+import "charm.land/lipgloss/v2"
+```
+
+**Install:**
+
+```bash
+go get charm.land/lipgloss/v2
+```
+
+All subpackages follow the same pattern:
+
+```go
+// v1
+import "github.com/charmbracelet/lipgloss/table"
+import "github.com/charmbracelet/lipgloss/tree"
+import "github.com/charmbracelet/lipgloss/list"
+
+// v2
+import "charm.land/lipgloss/v2/table"
+import "charm.land/lipgloss/v2/tree"
+import "charm.land/lipgloss/v2/list"
+```
+
+**Search-and-replace pattern:**
+
+```
+github.com/charmbracelet/lipgloss → charm.land/lipgloss/v2
+```
+
+---
+
+## Color System
+
+This is the most significant API change.
+
+### `Color` is now a function, not a type
+
+```go
+// v1 — Color is a string type
+var c lipgloss.Color = "21"
+var c lipgloss.Color = "#ff00ff"
+
+// v2 — Color is a function returning color.Color
+var c color.Color = lipgloss.Color("21")
+var c color.Color = lipgloss.Color("#ff00ff")
+```
+
+The return type is `image/color.Color` (from the standard library).
+
+### `TerminalColor` interface is removed
+
+All methods that accepted `lipgloss.TerminalColor` now accept
+`image/color.Color`:
+
+```go
+// v1
+func (s Style) Foreground(c TerminalColor) Style
+func (s Style) Background(c TerminalColor) Style
+func (s Style) BorderForeground(c ...TerminalColor) Style
+
+// v2
+func (s Style) Foreground(c color.Color) Style
+func (s Style) Background(c color.Color) Style
+func (s Style) BorderForeground(c ...color.Color) Style
+```
+
+**Migration:** Replace every `lipgloss.TerminalColor` with `color.Color` and
+add `import "image/color"`.
+
+### `ANSIColor` is now an alias
+
+```go
+// v1 — custom uint type
+type ANSIColor uint
+
+// v2 — alias for ansi.IndexedColor
+type ANSIColor = ansi.IndexedColor
+```
+
+v2 also exports named constants for the 16 basic ANSI colors:
+
+```go
+lipgloss.Black, lipgloss.Red, lipgloss.Green, lipgloss.Yellow,
+lipgloss.Blue, lipgloss.Magenta, lipgloss.Cyan, lipgloss.White,
+lipgloss.BrightBlack, lipgloss.BrightRed, lipgloss.BrightGreen,
+lipgloss.BrightYellow, lipgloss.BrightBlue, lipgloss.BrightMagenta,
+lipgloss.BrightCyan, lipgloss.BrightWhite
+```
+
+### `AdaptiveColor`, `CompleteColor`, `CompleteAdaptiveColor`
+
+These types have been moved out of the root package. Use the `compat` package
+for a drop-in replacement, or use the new `LightDark` and `Complete` helpers
+for explicit control:
+
+```go
+// v1
+color := lipgloss.AdaptiveColor{Light: "#0000ff", Dark: "#000099"}
+
+// v2 — using compat (quick path)
+color := compat.AdaptiveColor{
+ Light: lipgloss.Color("#0000ff"),
+ Dark: lipgloss.Color("#000099"),
+}
+
+// v2 — using LightDark (recommended)
+hasDark := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+lightDark := lipgloss.LightDark(hasDark)
+color := lightDark(lipgloss.Color("#0000ff"), lipgloss.Color("#000099"))
+```
+
+```go
+// v1
+color := lipgloss.CompleteColor{TrueColor: "#ff00ff", ANSI256: "200", ANSI: "5"}
+
+// v2 — using compat
+color := compat.CompleteColor{
+ TrueColor: lipgloss.Color("#ff00ff"),
+ ANSI256: lipgloss.Color("200"),
+ ANSI: lipgloss.Color("5"),
+}
+
+// v2 — using Complete (recommended)
+profile := colorprofile.Detect(os.Stdout, os.Environ())
+complete := lipgloss.Complete(profile)
+color := complete(lipgloss.Color("5"), lipgloss.Color("200"), lipgloss.Color("#ff00ff"))
+```
+
+Note that `compat.AdaptiveColor` and friends take `color.Color` values for
+their fields, not strings.
+
+---
+
+## Renderer Removal
+
+The `Renderer` type and all associated functions are removed. In v1, every
+`Style` carried a `*Renderer` pointer and the package maintained a global
+default renderer.
+
+```go
+// v1 — these no longer exist
+lipgloss.DefaultRenderer()
+lipgloss.SetDefaultRenderer(r)
+lipgloss.NewRenderer(w, opts...)
+lipgloss.ColorProfile()
+lipgloss.SetColorProfile(p)
+renderer.NewStyle()
+```
+
+**In v2, `Style` is a plain value type.** There is no renderer. Color
+downsampling is handled at the output layer (see next section).
+
+**Migration:**
+
+- Replace `lipgloss.DefaultRenderer().NewStyle()` with `lipgloss.NewStyle()`.
+- Replace `renderer.NewStyle()` with `lipgloss.NewStyle()`.
+- Remove any `*Renderer` fields from your types.
+- Remove calls to `SetColorProfile` — use `colorprofile.Detect` at the output
+ layer instead.
+
+---
+
+## Printing and Color Downsampling
+
+In v1, color downsampling happened inside `Style.Render()` via the renderer. In
+v2, `Render()` always emits full-fidelity ANSI. Downsampling happens when you
+print.
+
+### Standalone Usage
+
+Use the Lip Gloss writer functions:
+
+```go
+s := someStyle.Render("Hello!")
+
+// Print to stdout with automatic downsampling
+lipgloss.Println(s)
+
+// Print to stderr
+lipgloss.Fprintln(os.Stderr, s)
+
+// Render to a string (downsampled for stdout's profile)
+str := lipgloss.Sprint(s)
+```
+
+The default writer targets `stdout`. To customize:
+
+```go
+lipgloss.Writer = colorprofile.NewWriter(os.Stderr, os.Environ())
+```
+
+### With Bubble Tea
+
+No changes needed. Bubble Tea v2 handles downsampling internally.
+
+---
+
+## Background Detection and Adaptive Colors
+
+### Standalone
+
+v1 detected the background color automatically via the global renderer. v2
+requires explicit queries:
+
+```go
+// v1
+hasDark := lipgloss.HasDarkBackground()
+
+// v2 — specify the input and output
+hasDark := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+```
+
+Then use `LightDark` to pick colors:
+
+```go
+lightDark := lipgloss.LightDark(hasDark)
+fg := lightDark(lipgloss.Color("#333333"), lipgloss.Color("#f1f1f1"))
+
+s := lipgloss.NewStyle().Foreground(fg)
+```
+
+### With Bubble Tea
+
+Request the background color in `Init` and listen for the response:
+
+```go
+func (m model) Init() tea.Cmd {
+ return tea.RequestBackgroundColor
+}
+
+func (m model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
+ switch msg := msg.(type) {
+ case tea.BackgroundColorMsg:
+ m.styles = newStyles(msg.IsDark())
+ }
+ // ...
+}
+
+func newStyles(bgIsDark bool) styles {
+ lightDark := lipgloss.LightDark(bgIsDark)
+ return styles{
+ title: lipgloss.NewStyle().Foreground(lightDark(
+ lipgloss.Color("#333333"),
+ lipgloss.Color("#f1f1f1"),
+ )),
+ }
+}
+```
+
+---
+
+## Whitespace Options
+
+The separate foreground/background whitespace options have been replaced by a
+single style option:
+
+```go
+// v1
+lipgloss.Place(width, height, hPos, vPos, str,
+ lipgloss.WithWhitespaceForeground(lipgloss.Color("#333")),
+ lipgloss.WithWhitespaceBackground(lipgloss.Color("#000")),
+)
+
+// v2
+lipgloss.Place(width, height, hPos, vPos, str,
+ lipgloss.WithWhitespaceStyle(lipgloss.NewStyle().
+ Foreground(lipgloss.Color("#333")).
+ Background(lipgloss.Color("#000")),
+ ),
+)
+```
+
+---
+
+## Underline
+
+`Underline(bool)` still works for basic on/off. v2 adds fine-grained control:
+
+```go
+// v1
+s := lipgloss.NewStyle().Underline(true)
+
+// v2 — still works
+s := lipgloss.NewStyle().Underline(true)
+
+// v2 — new: specific styles
+s := lipgloss.NewStyle().UnderlineStyle(lipgloss.UnderlineCurly)
+
+// v2 — new: colored underlines
+s := lipgloss.NewStyle().
+ UnderlineStyle(lipgloss.UnderlineSingle).
+ UnderlineColor(lipgloss.Color("#FF0000"))
+```
+
+Internally, `Underline(true)` is equivalent to `UnderlineStyle(UnderlineSingle)`
+and `Underline(false)` is equivalent to `UnderlineStyle(UnderlineNone)`.
+
+---
+
+## Style API Changes
+
+### `NewStyle()` is no longer tied to a Renderer
+
+```go
+// v1
+s := lipgloss.NewStyle() // uses global renderer
+s := renderer.NewStyle() // uses specific renderer
+
+// v2
+s := lipgloss.NewStyle() // pure value, no renderer
+```
+
+### Color getters return `color.Color`
+
+```go
+// v1
+fg := s.GetForeground() // returns TerminalColor
+
+// v2
+fg := s.GetForeground() // returns color.Color
+```
+
+### New style methods
+
+| Method | Description |
+|---|---|
+| `UnderlineStyle(Underline)` | Set underline style (single, double, curly, etc.) |
+| `UnderlineColor(color.Color)` | Set underline color |
+| `PaddingChar(rune)` | Set the character used for padding fill |
+| `MarginChar(rune)` | Set the character used for margin fill |
+| `Hyperlink(link, params...)` | Set a clickable hyperlink |
+| `BorderForegroundBlend(...color.Color)` | Apply gradient colors to borders |
+| `BorderForegroundBlendOffset(int)` | Set the offset for border gradient |
+
+Each has a corresponding `Get*`, `Unset*`, and where applicable `Get*`
+accessor.
+
+---
+
+## Tree Subpackage
+
+The import path changes and there are new styling options:
+
+```go
+// v1
+import "github.com/charmbracelet/lipgloss/tree"
+
+// v2
+import "charm.land/lipgloss/v2/tree"
+```
+
+New methods:
+
+- `IndenterStyle(lipgloss.Style)` — set a static style for tree indentation.
+- `IndenterStyleFunc(func(Children, int) lipgloss.Style)` — conditionally style
+ indentation.
+- `Width(int)` — set tree width for padding.
+
+---
+
+## Removed APIs
+
+The following types and functions no longer exist in v2. This table shows each
+removed symbol and its replacement.
+
+| v1 Symbol | v2 Replacement |
+|---|---|
+| `type Renderer` | Removed entirely |
+| `DefaultRenderer()` | Not needed |
+| `SetDefaultRenderer(r)` | Not needed |
+| `NewRenderer(w, opts...)` | Not needed |
+| `ColorProfile()` | `colorprofile.Detect(w, env)` |
+| `SetColorProfile(p)` | Set `lipgloss.Writer.Profile` |
+| `HasDarkBackground()` (no args) | `lipgloss.HasDarkBackground(in, out)` |
+| `SetHasDarkBackground(b)` | Not needed — pass bool to `LightDark` |
+| `type TerminalColor` | `image/color.Color` |
+| `type Color string` | `func Color(string) color.Color` |
+| `type ANSIColor uint` | `type ANSIColor = ansi.IndexedColor` |
+| `type AdaptiveColor` | `compat.AdaptiveColor` or `LightDark` |
+| `type CompleteColor` | `compat.CompleteColor` or `Complete` |
+| `type CompleteAdaptiveColor` | `compat.CompleteAdaptiveColor` |
+| `WithWhitespaceForeground(c)` | `WithWhitespaceStyle(s)` |
+| `WithWhitespaceBackground(c)` | `WithWhitespaceStyle(s)` |
+| `renderer.NewStyle()` | `lipgloss.NewStyle()` |
+
+---
+
+## Quick Reference Table
+
+A side-by-side summary for common patterns:
+
+| Task | v1 | v2 |
+|---|---|---|
+| Import | `"github.com/charmbracelet/lipgloss"` | `"charm.land/lipgloss/v2"` |
+| Create style | `lipgloss.NewStyle()` | `lipgloss.NewStyle()` |
+| Hex color | `lipgloss.Color("#ff00ff")` | `lipgloss.Color("#ff00ff")` |
+| ANSI color | `lipgloss.Color("5")` | `lipgloss.Color("5")` or `lipgloss.Magenta` |
+| Adaptive color | `lipgloss.AdaptiveColor{Light: "#fff", Dark: "#000"}` | `compat.AdaptiveColor{Light: lipgloss.Color("#fff"), Dark: lipgloss.Color("#000")}` |
+| Set foreground | `s.Foreground(lipgloss.Color("5"))` | `s.Foreground(lipgloss.Color("5"))` |
+| Print with downsampling | `fmt.Println(s.Render("hi"))` | `lipgloss.Println(s.Render("hi"))` |
+| Detect dark bg | `lipgloss.HasDarkBackground()` | `lipgloss.HasDarkBackground(os.Stdin, os.Stdout)` |
+| Light/dark color | `lipgloss.AdaptiveColor{...}` | `lipgloss.LightDark(isDark)(light, dark)` |
+| Whitespace styling | `WithWhitespaceForeground(c)` | `WithWhitespaceStyle(lipgloss.NewStyle().Foreground(c))` |
+| Underline | `s.Underline(true)` | `s.Underline(true)` or `s.UnderlineStyle(lipgloss.UnderlineCurly)` |
+
+---
+
+## Feedback
+
+Questions, issues, or feedback:
+
+- [Discord](https://charm.land/discord)
+- [Matrix](https://charm.land/matrix)
+- [Email](mailto:vt100@charm.land)
+
+---
+
+Part of [Charm](https://charm.land).
+
+
+
+Charm热爱开源 • Charm loves open source • نحنُ نحب المصادر المفتوحة
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/align.go b/tools/vendor/charm.land/lipgloss/v2/align.go
similarity index 89%
rename from tools/vendor/github.com/charmbracelet/lipgloss/align.go
rename to tools/vendor/charm.land/lipgloss/v2/align.go
index ce654b232..d196213b7 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/align.go
+++ b/tools/vendor/charm.land/lipgloss/v2/align.go
@@ -4,13 +4,12 @@ import (
"strings"
"github.com/charmbracelet/x/ansi"
- "github.com/muesli/termenv"
)
// Perform text alignment. If the string is multi-lined, we also make all lines
-// the same width by padding them with spaces. If a termenv style is passed,
-// use that to style the spaces added.
-func alignTextHorizontal(str string, pos Position, width int, style *termenv.Style) string {
+// the same width by padding them with spaces. If a style is passed, use that
+// to style the spaces added.
+func alignTextHorizontal(str string, pos Position, width int, style *ansi.Style) string {
lines, widestLine := getLines(str)
var b strings.Builder
@@ -21,7 +20,7 @@ func alignTextHorizontal(str string, pos Position, width int, style *termenv.Sty
shortAmount += max(0, width-(shortAmount+lineWidth)) // difference from the total width, if set
if shortAmount > 0 {
- switch pos { //nolint:exhaustive
+ switch pos {
case Right:
s := strings.Repeat(" ", shortAmount)
if style != nil {
@@ -59,7 +58,7 @@ func alignTextHorizontal(str string, pos Position, width int, style *termenv.Sty
return b.String()
}
-func alignTextVertical(str string, pos Position, height int, _ *termenv.Style) string {
+func alignTextVertical(str string, pos Position, height int, _ *ansi.Style) string {
strHeight := strings.Count(str, "\n") + 1
if height < strHeight {
return str
diff --git a/tools/vendor/charm.land/lipgloss/v2/ansi_unix.go b/tools/vendor/charm.land/lipgloss/v2/ansi_unix.go
new file mode 100644
index 000000000..b4fca7d19
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/ansi_unix.go
@@ -0,0 +1,8 @@
+//go:build !windows
+
+package lipgloss
+
+import "os"
+
+// EnableLegacyWindowsANSI is only needed on Windows.
+func EnableLegacyWindowsANSI(*os.File) {}
diff --git a/tools/vendor/charm.land/lipgloss/v2/ansi_windows.go b/tools/vendor/charm.land/lipgloss/v2/ansi_windows.go
new file mode 100644
index 000000000..8a1ef00eb
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/ansi_windows.go
@@ -0,0 +1,30 @@
+//go:build windows
+
+package lipgloss
+
+import (
+ "os"
+
+ "golang.org/x/sys/windows"
+)
+
+// EnableLegacyWindowsANSI enables support for ANSI color sequences in the
+// Windows default console (cmd.exe and the PowerShell application). Note that
+// this only works with Windows 10 and greater. Also note that Windows Terminal
+// supports colors by default.
+func EnableLegacyWindowsANSI(f *os.File) {
+ var mode uint32
+ handle := windows.Handle(f.Fd())
+ err := windows.GetConsoleMode(handle, &mode)
+ if err != nil {
+ return
+ }
+
+ // See https://docs.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences
+ if mode&windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING != windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING {
+ vtpmode := mode | windows.ENABLE_VIRTUAL_TERMINAL_PROCESSING
+ if err := windows.SetConsoleMode(handle, vtpmode); err != nil {
+ return
+ }
+ }
+}
diff --git a/tools/vendor/charm.land/lipgloss/v2/blending.go b/tools/vendor/charm.land/lipgloss/v2/blending.go
new file mode 100644
index 000000000..82830f3e4
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/blending.go
@@ -0,0 +1,196 @@
+package lipgloss
+
+import (
+ "image/color"
+ "math"
+ "slices"
+
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+// Blend1D blends a series of colors together in one linear dimension using multiple
+// stops, into the provided number of steps. Uses the "CIE L*, a*, b*" (CIELAB) color-space.
+//
+// Note that if any of the provided colors are completely transparent, we will
+// assume that the alpha value was lost in conversion from RGB -> RGBA, and we
+// will set the alpha to opaque, as it's not possible to blend something completely
+// transparent.
+func Blend1D(steps int, stops ...color.Color) []color.Color {
+ if steps < 0 {
+ steps = 0
+ }
+
+ if steps <= len(stops) {
+ return stops[:steps]
+ }
+
+ // Ensure they didn't provide any nil colors.
+ stops = slices.DeleteFunc(stops, func(c color.Color) bool {
+ return c == nil
+ })
+
+ if len(stops) == 0 {
+ return nil // We can't safely fallback.
+ }
+
+ // If they only provided one valid color (or some nil colors), we will just return
+ // an array of that color, for the amount of steps they requested.
+ if len(stops) == 1 {
+ singleColor := stops[0]
+ result := make([]color.Color, steps)
+ for i := range result {
+ result[i] = singleColor
+ }
+ return result
+ }
+
+ blended := make([]color.Color, steps)
+
+ // Convert stops to colorful.Color once
+ cstops := make([]colorful.Color, len(stops))
+ for i, k := range stops {
+ cstops[i], _ = colorful.MakeColor(ensureNotTransparent(k))
+ }
+
+ numSegments := len(cstops) - 1
+ defaultSize := steps / numSegments
+ remainingSteps := steps % numSegments
+
+ resultIndex := 0
+ for i := range numSegments {
+ from := cstops[i]
+ to := cstops[i+1]
+
+ // Calculate segment size.
+ segmentSize := defaultSize
+ if i < remainingSteps {
+ segmentSize++
+ }
+
+ divisor := float64(segmentSize - 1)
+
+ // Generate colors for this segment.
+ for j := 0; j < segmentSize; j++ {
+ var blendingFactor float64
+ if segmentSize > 1 {
+ blendingFactor = float64(j) / divisor
+ }
+ blended[resultIndex] = from.BlendLab(to, blendingFactor).Clamped()
+ resultIndex++
+ }
+ }
+
+ return blended
+}
+
+// Blend2D blends a series of colors together in two linear dimensions using
+// multiple stops, into the provided width/height. Uses the "CIE L*, a*, b*" (CIELAB)
+// color-space. The angle parameter controls the rotation of the gradient (0-360°),
+// where 0° is left-to-right, 45° is bottom-left to top-right (diagonal). The function
+// returns colors in a 1D row-major order ([row1, row2, row3, ...]).
+//
+// Example of how to iterate over the result:
+//
+// gradient := colors.Blend2D(width, height, 180, color1, color2, color3, ...)
+// gradientContent := strings.Builder{}
+// for y := range height {
+// for x := range width {
+// index := y*width + x
+// gradientContent.WriteString(
+// lipgloss.NewStyle().
+// Background(gradient[index]).
+// Render(" "),
+// )
+// }
+// if y < height-1 { // End of row.
+// gradientContent.WriteString("\n")
+// }
+// }
+//
+// Note that if any of the provided colors are completely transparent, we will
+// assume that the alpha value was lost in conversion from RGB -> RGBA, and we
+// will set the alpha to opaque, as it's not possible to blend something completely
+// transparent.
+func Blend2D(width, height int, angle float64, stops ...color.Color) []color.Color {
+ if width < 1 {
+ width = 1
+ }
+ if height < 1 {
+ height = 1
+ }
+
+ // Normalize angle to 0-360.
+ angle = math.Mod(angle, 360)
+ if angle < 0 {
+ angle += 360
+ }
+
+ // Ensure they didn't provide any nil colors.
+ stops = slices.DeleteFunc(stops, func(c color.Color) bool {
+ return c == nil
+ })
+
+ if len(stops) == 0 {
+ return nil // We can't safely fallback.
+ }
+
+ // If they only provided one valid color (or some nil colors), we will just return
+ // an array of that color, for the amount of pixels they requested.
+ if len(stops) == 1 {
+ singleColor := stops[0]
+ result := make([]color.Color, width*height)
+ for i := range result {
+ result[i] = singleColor
+ }
+ return result
+ }
+
+ // For 2D blending, we'll create a gradient along the diagonal and then sample
+ // from it based on the angle. We'll use the maximum dimension to ensure we have
+ // enough resolution for the gradient.
+ diagonalGradient := Blend1D(max(width, height), stops...)
+
+ result := make([]color.Color, width*height)
+
+ // Calculate center point for rotation.
+ centerX := float64(width-1) / 2.0
+ centerY := float64(height-1) / 2.0
+
+ angleRad := angle * math.Pi / 180.0 // -> radians.
+
+ // Pre-calculate sin and cos.
+ cosAngle := math.Cos(angleRad)
+ sinAngle := math.Sin(angleRad)
+
+ // Calculate diagonal length for proper gradient mapping.
+ diagonalLength := math.Sqrt(float64(width*width + height*height))
+
+ // Pre-calculate gradient length for index calculation.
+ gradientLen := float64(len(diagonalGradient) - 1)
+
+ for y := range height {
+ // Calculate the distance from center along the gradient direction.
+ dy := float64(y) - centerY
+
+ for x := 0; x < width; x++ {
+ // Calculate the distance from center along the gradient direction.
+ dx := float64(x) - centerX
+
+ rotX := dx*cosAngle - dy*sinAngle // Rotate the point by the angle.
+
+ // Map the rotated position to the gradient. Normalize to 0-1 range based on
+ // the diagonal length.
+ gradientPos := clamp((rotX+diagonalLength/2.0)/diagonalLength, 0, 1)
+
+ // Calculate the index in the gradient.
+ gradientIndex := int(gradientPos * gradientLen)
+ if gradientIndex >= len(diagonalGradient) {
+ gradientIndex = len(diagonalGradient) - 1
+ }
+
+ result[y*width+x] = diagonalGradient[gradientIndex] // -> row-major order.
+ }
+ }
+
+ return result
+}
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/borders.go b/tools/vendor/charm.land/lipgloss/v2/borders.go
similarity index 73%
rename from tools/vendor/github.com/charmbracelet/lipgloss/borders.go
rename to tools/vendor/charm.land/lipgloss/v2/borders.go
index b36f87438..7f12360f6 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/borders.go
+++ b/tools/vendor/charm.land/lipgloss/v2/borders.go
@@ -1,10 +1,13 @@
package lipgloss
import (
+ "image/color"
+ "slices"
"strings"
+ "unicode/utf8"
"github.com/charmbracelet/x/ansi"
- "github.com/muesli/termenv"
+ "github.com/clipperhouse/displaywidth"
"github.com/rivo/uniseg"
)
@@ -56,10 +59,7 @@ func (b Border) GetLeftSize() int {
func getBorderEdgeWidth(borderParts ...string) (maxWidth int) {
for _, piece := range borderParts {
- w := maxRuneWidth(piece)
- if w > maxWidth {
- maxWidth = w
- }
+ maxWidth = max(maxWidth, maxRuneWidth(piece))
}
return maxWidth
}
@@ -278,6 +278,52 @@ func ASCIIBorder() Border {
return asciiBorder
}
+type borderBlend struct {
+ topGradient []color.Color
+ rightGradient []color.Color
+ bottomGradient []color.Color
+ leftGradient []color.Color
+}
+
+func (s Style) borderBlend(width, height int, colors ...color.Color) *borderBlend {
+ gradient := Blend1D(
+ (height+width+2)*2,
+ colors...,
+ )
+
+ // Rotate array forward or reverse based on the offset if provided.
+ if r := -s.getAsInt(borderForegroundBlendOffsetKey); r != 0 {
+ n := len(gradient)
+ r %= n
+ if r < 0 {
+ r += n
+ }
+ slices.Reverse(gradient[:r])
+ slices.Reverse(gradient[r:])
+ slices.Reverse(gradient)
+ }
+
+ offset := 0
+ getFromOffset := func(size int) (s []color.Color) {
+ s = gradient[offset : offset+size]
+ offset += size
+ return s
+ }
+
+ blend := &borderBlend{
+ topGradient: getFromOffset(width + 2),
+ rightGradient: getFromOffset(height),
+ bottomGradient: getFromOffset(width + 2),
+ leftGradient: getFromOffset(height),
+ }
+
+ // bottom and left gradients are reversed because they are drawn in reverse order.
+ slices.Reverse(blend.bottomGradient)
+ slices.Reverse(blend.leftGradient)
+
+ return blend
+}
+
func (s Style) applyBorder(str string) string {
var (
border = s.getBorderStyle()
@@ -285,21 +331,11 @@ func (s Style) applyBorder(str string) string {
hasRight = s.getAsBool(borderRightKey, false)
hasBottom = s.getAsBool(borderBottomKey, false)
hasLeft = s.getAsBool(borderLeftKey, false)
-
- topFG = s.getAsColor(borderTopForegroundKey)
- rightFG = s.getAsColor(borderRightForegroundKey)
- bottomFG = s.getAsColor(borderBottomForegroundKey)
- leftFG = s.getAsColor(borderLeftForegroundKey)
-
- topBG = s.getAsColor(borderTopBackgroundKey)
- rightBG = s.getAsColor(borderRightBackgroundKey)
- bottomBG = s.getAsColor(borderBottomBackgroundKey)
- leftBG = s.getAsColor(borderLeftBackgroundKey)
)
// If a border is set and no sides have been specifically turned on or off
// render borders on all sides.
- if s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
hasTop = true
hasRight = true
hasBottom = true
@@ -320,8 +356,11 @@ func (s Style) applyBorder(str string) string {
width += maxRuneWidth(border.Left)
}
- if hasRight && border.Right == "" {
- border.Right = " "
+ if hasRight {
+ if border.Right == "" {
+ border.Right = " "
+ }
+ width += maxRuneWidth(border.Right)
}
// If corners should be rendered but are set with the empty string, fill them
@@ -370,13 +409,35 @@ func (s Style) applyBorder(str string) string {
border.BottomRight = getFirstRuneAsString(border.BottomRight)
border.BottomLeft = getFirstRuneAsString(border.BottomLeft)
+ var topFG, rightFG, bottomFG, leftFG color.Color
+ var (
+ blendFG = s.getAsColors(borderForegroundBlendKey)
+ topBG = s.getAsColor(borderTopBackgroundKey)
+ rightBG = s.getAsColor(borderRightBackgroundKey)
+ bottomBG = s.getAsColor(borderBottomBackgroundKey)
+ leftBG = s.getAsColor(borderLeftBackgroundKey)
+ )
+
+ var blend *borderBlend
+ if len(blendFG) > 0 {
+ blend = s.borderBlend(width, len(lines), blendFG...)
+ } else {
+ topFG = s.getAsColor(borderTopForegroundKey)
+ rightFG = s.getAsColor(borderRightForegroundKey)
+ bottomFG = s.getAsColor(borderBottomForegroundKey)
+ leftFG = s.getAsColor(borderLeftForegroundKey)
+ }
+
var out strings.Builder
// Render top
if hasTop {
top := renderHorizontalEdge(border.TopLeft, border.Top, border.TopRight, width)
- top = s.styleBorder(top, topFG, topBG)
- out.WriteString(top)
+ if blend != nil {
+ out.WriteString(s.styleBorderBlend(top, blend.topGradient, topBG))
+ } else {
+ out.WriteString(s.styleBorder(top, topFG, topBG))
+ }
out.WriteRune('\n')
}
@@ -387,23 +448,32 @@ func (s Style) applyBorder(str string) string {
rightIndex := 0
// Render sides
+ var r string
for i, l := range lines {
if hasLeft {
- r := string(leftRunes[leftIndex])
+ r = string(leftRunes[leftIndex])
leftIndex++
if leftIndex >= len(leftRunes) {
leftIndex = 0
}
- out.WriteString(s.styleBorder(r, leftFG, leftBG))
+ if blend != nil {
+ out.WriteString(s.styleBorder(r, blend.leftGradient[i], leftBG))
+ } else {
+ out.WriteString(s.styleBorder(r, leftFG, leftBG))
+ }
}
out.WriteString(l)
if hasRight {
- r := string(rightRunes[rightIndex])
+ r = string(rightRunes[rightIndex])
rightIndex++
if rightIndex >= len(rightRunes) {
rightIndex = 0
}
- out.WriteString(s.styleBorder(r, rightFG, rightBG))
+ if blend != nil {
+ out.WriteString(s.styleBorder(r, blend.rightGradient[i], rightBG))
+ } else {
+ out.WriteString(s.styleBorder(r, rightFG, rightBG))
+ }
}
if i < len(lines)-1 {
out.WriteRune('\n')
@@ -413,9 +483,12 @@ func (s Style) applyBorder(str string) string {
// Render bottom
if hasBottom {
bottom := renderHorizontalEdge(border.BottomLeft, border.Bottom, border.BottomRight, width)
- bottom = s.styleBorder(bottom, bottomFG, bottomBG)
out.WriteRune('\n')
- out.WriteString(bottom)
+ if blend != nil {
+ out.WriteString(s.styleBorderBlend(bottom, blend.bottomGradient, bottomBG))
+ } else {
+ out.WriteString(s.styleBorder(bottom, bottomFG, bottomBG))
+ }
}
return out.String()
@@ -435,49 +508,73 @@ func renderHorizontalEdge(left, middle, right string, width int) string {
out := strings.Builder{}
out.WriteString(left)
- for i := leftWidth + rightWidth; i < width+rightWidth; {
- out.WriteRune(runes[j])
+
+ for i := 0; i < width-leftWidth-rightWidth; {
+ r := runes[j]
+ out.WriteRune(r)
+ i += ansi.StringWidth(string(r))
j++
if j >= len(runes) {
j = 0
}
- i += ansi.StringWidth(string(runes[j]))
}
- out.WriteString(right)
+ out.WriteString(right)
return out.String()
}
-// Apply foreground and background styling to a border.
-func (s Style) styleBorder(border string, fg, bg TerminalColor) string {
+// styleBorder applies foreground and background styling to a border.
+func (s Style) styleBorder(border string, fg, bg color.Color) string {
if fg == noColor && bg == noColor {
return border
}
-
- style := termenv.Style{}
-
+ var style ansi.Style
if fg != noColor {
- style = style.Foreground(fg.color(s.r))
+ style = style.ForegroundColor(fg)
}
if bg != noColor {
- style = style.Background(bg.color(s.r))
+ style = style.BackgroundColor(bg)
}
-
return style.Styled(border)
}
+// styleBorderBlend applies foreground and background styling to a border, using blending.
+func (s Style) styleBorderBlend(border string, fg []color.Color, bg color.Color) string {
+ var out strings.Builder
+ var style ansi.Style
+ var i int
+
+ gr := uniseg.NewGraphemes(border)
+ for gr.Next() {
+ style = style[:0]
+ if fg[i] != noColor {
+ style = style.ForegroundColor(fg[i])
+ }
+ if bg != noColor {
+ style = style.BackgroundColor(bg)
+ }
+ _, _ = out.WriteString(style.String())
+ _, _ = out.Write(gr.Bytes())
+ i++
+ }
+ _, _ = out.WriteString(ansi.ResetStyle)
+ return out.String()
+}
+
func maxRuneWidth(str string) int {
+ switch len(str) {
+ case 0:
+ return 0
+ case 1:
+ return displaywidth.String(str)
+ }
+
var width int
- state := -1
- for len(str) > 0 {
- var w int
- _, str, w, state = uniseg.FirstGraphemeClusterInString(str, state)
- if w > width {
- width = w
- }
+ g := displaywidth.StringGraphemes(str)
+ for g.Next() {
+ width = max(width, g.Width())
}
-
return width
}
@@ -485,6 +582,6 @@ func getFirstRuneAsString(str string) string {
if str == "" {
return str
}
- r := []rune(str)
- return string(r[0])
+ _, size := utf8.DecodeRuneInString(str)
+ return str[:size]
}
diff --git a/tools/vendor/charm.land/lipgloss/v2/canvas.go b/tools/vendor/charm.land/lipgloss/v2/canvas.go
new file mode 100644
index 000000000..396defb8b
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/canvas.go
@@ -0,0 +1,88 @@
+package lipgloss
+
+import (
+ uv "github.com/charmbracelet/ultraviolet"
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Canvas is a cell-buffer that can be used to compose and draw [uv.Drawable]s
+// like [Layer]s.
+//
+// Composed drawables are drawn onto the canvas in the order they were
+// composed, meaning later drawables will appear "on top" of earlier ones.
+//
+// A canvas can read, modify, and render its cell contents.
+//
+// It implements [uv.Screen] and [uv.Drawable].
+type Canvas struct {
+ scr uv.ScreenBuffer
+}
+
+var _ uv.Screen = (*Canvas)(nil)
+
+// NewCanvas creates a new [Canvas] with the given size.
+func NewCanvas(width, height int) *Canvas {
+ c := new(Canvas)
+ c.scr = uv.NewScreenBuffer(width, height)
+ c.scr.Method = ansi.GraphemeWidth
+ return c
+}
+
+// Resize resizes the canvas to the given width and height.
+func (c *Canvas) Resize(width, height int) {
+ c.scr.Resize(width, height)
+}
+
+// Clear clears the canvas.
+func (c *Canvas) Clear() {
+ c.scr.Clear()
+}
+
+// Bounds implements [uv.Screen].
+func (c *Canvas) Bounds() uv.Rectangle {
+ return c.scr.Bounds()
+}
+
+// Width returns the width of the canvas.
+func (c *Canvas) Width() int {
+ return c.scr.Width()
+}
+
+// Height returns the height of the canvas.
+func (c *Canvas) Height() int {
+ return c.scr.Height()
+}
+
+// CellAt implements [uv.Screen].
+func (c *Canvas) CellAt(x int, y int) *uv.Cell {
+ return c.scr.CellAt(x, y)
+}
+
+// SetCell implements [uv.Screen].
+func (c *Canvas) SetCell(x int, y int, cell *uv.Cell) {
+ c.scr.SetCell(x, y, cell)
+}
+
+// WidthMethod implements [uv.Screen].
+func (c *Canvas) WidthMethod() uv.WidthMethod {
+ return c.scr.WidthMethod()
+}
+
+// Compose composes a [Layer] or any [uv.Drawable] onto the [Canvas].
+func (c *Canvas) Compose(drawer uv.Drawable) *Canvas {
+ drawer.Draw(c, c.Bounds())
+ return c
+}
+
+// Draw draws the [Canvas] onto the given [uv.Screen] within the specified
+// area.
+//
+// It implements [uv.Drawable].
+func (c *Canvas) Draw(scr uv.Screen, area uv.Rectangle) {
+ c.scr.Draw(scr, area)
+}
+
+// Render renders the canvas into a styled string.
+func (c *Canvas) Render() string {
+ return c.scr.Render()
+}
diff --git a/tools/vendor/charm.land/lipgloss/v2/color.go b/tools/vendor/charm.land/lipgloss/v2/color.go
new file mode 100644
index 000000000..7443dc10b
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/color.go
@@ -0,0 +1,359 @@
+package lipgloss
+
+import (
+ "cmp"
+ "errors"
+ "image/color"
+ "strconv"
+ "strings"
+
+ "github.com/charmbracelet/colorprofile"
+ "github.com/charmbracelet/x/ansi"
+ "github.com/lucasb-eyer/go-colorful"
+)
+
+func clamp[T cmp.Ordered](v, low, high T) T {
+ if high < low {
+ high, low = low, high
+ }
+ return min(high, max(low, v))
+}
+
+// 4-bit color constants.
+const (
+ Black ansi.BasicColor = iota
+ Red
+ Green
+ Yellow
+ Blue
+ Magenta
+ Cyan
+ White
+
+ BrightBlack
+ BrightRed
+ BrightGreen
+ BrightYellow
+ BrightBlue
+ BrightMagenta
+ BrightCyan
+ BrightWhite
+)
+
+var noColor = NoColor{}
+
+// NoColor is used to specify the absence of color styling. When this is active
+// foreground colors will be rendered with the terminal's default text color,
+// and background colors will not be drawn at all.
+//
+// Example usage:
+//
+// var style = someStyle.Background(lipgloss.NoColor{})
+type NoColor struct{}
+
+// RGBA returns the RGBA value of this color. Because we have to return
+// something, despite this color being the absence of color, we're returning
+// black with 100% opacity.
+//
+// Red: 0x0, Green: 0x0, Blue: 0x0, Alpha: 0xFFFF.
+func (n NoColor) RGBA() (r, g, b, a uint32) {
+ return 0x0, 0x0, 0x0, 0xFFFF //nolint:mnd
+}
+
+// Color specifies a color by hex or ANSI256 value. For example:
+//
+// ansiColor := lipgloss.Color("1") // The same as lipgloss.Red
+// ansi256Color := lipgloss.Color("21")
+// hexColor := lipgloss.Color("#0000ff")
+func Color(s string) color.Color {
+ if strings.HasPrefix(s, "#") {
+ c, err := parseHex(s)
+ if err != nil {
+ return noColor
+ }
+ return c
+ }
+
+ i, err := strconv.Atoi(s)
+ if err != nil {
+ return noColor
+ }
+
+ if i < 0 {
+ // Only positive numbers
+ i = -i
+ }
+
+ if i < 16 {
+ return ansi.BasicColor(i) //nolint:gosec
+ } else if i < 256 {
+ return ANSIColor(i) //nolint:gosec
+ }
+
+ r, g, b := uint8((i>>16)&0xff), uint8(i>>8&0xff), uint8(i&0xff) //nolint:gosec
+ return color.RGBA{R: r, G: g, B: b, A: 0xff}
+}
+
+var errInvalidFormat = errors.New("invalid hex format") // pre-allocated.
+
+// parseHex parses a hex color string and returns a color.RGBA. The string can be
+// in the format #RRGGBB or #RGB. This is a more performant implementation of
+// [colorful.Hex].
+func parseHex(s string) (c color.RGBA, err error) {
+ c.A = 0xff
+
+ if len(s) == 0 || s[0] != '#' {
+ return c, errInvalidFormat
+ }
+
+ hexToByte := func(b byte) byte {
+ switch {
+ case b >= '0' && b <= '9':
+ return b - '0'
+ case b >= 'a' && b <= 'f':
+ return b - 'a' + 10
+ case b >= 'A' && b <= 'F':
+ return b - 'A' + 10
+ }
+ err = errInvalidFormat
+ return 0
+ }
+
+ switch len(s) {
+ case 7:
+ c.R = hexToByte(s[1])<<4 + hexToByte(s[2])
+ c.G = hexToByte(s[3])<<4 + hexToByte(s[4])
+ c.B = hexToByte(s[5])<<4 + hexToByte(s[6])
+ case 4:
+ c.R = hexToByte(s[1]) * 17
+ c.G = hexToByte(s[2]) * 17
+ c.B = hexToByte(s[3]) * 17
+ default:
+ err = errInvalidFormat
+ }
+ return c, err
+}
+
+// RGBColor is a color specified by red, green, and blue values.
+type RGBColor struct {
+ R uint8
+ G uint8
+ B uint8
+}
+
+// RGBA returns the RGBA value of this color. This satisfies the Go Color
+// interface.
+func (c RGBColor) RGBA() (r, g, b, a uint32) {
+ const shift = 8
+ r |= uint32(c.R) << shift
+ g |= uint32(c.G) << shift
+ b |= uint32(c.B) << shift
+ a = 0xFFFF
+ return
+}
+
+// ANSIColor is a color specified by an ANSI256 color value.
+//
+// Example usage:
+//
+// colorA := lipgloss.ANSIColor(8)
+// colorB := lipgloss.ANSIColor(134)
+type ANSIColor = ansi.IndexedColor
+
+// LightDarkFunc is a function that returns a color based on whether the
+// terminal has a light or dark background. You can create one of these with
+// [LightDark].
+//
+// Example:
+//
+// lightDark := lipgloss.LightDark(hasDarkBackground)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+//
+// For more info see [LightDark].
+type LightDarkFunc func(light, dark color.Color) color.Color
+
+// LightDark is a simple helper type that can be used to choose the appropriate
+// color based on whether the terminal has a light or dark background.
+//
+// lightDark := lipgloss.LightDark(hasDarkBackground)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+//
+// In practice, there are slightly different workflows between Bubble Tea and
+// Lip Gloss standalone.
+//
+// In Bubble Tea, listen for tea.BackgroundColorMsg, which automatically
+// flows through Update on start. This message will be received whenever the
+// background color changes:
+//
+// case tea.BackgroundColorMsg:
+// m.hasDarkBackground = msg.IsDark()
+//
+// Later, when you're rendering use:
+//
+// lightDark := lipgloss.LightDark(m.hasDarkBackground)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+//
+// In standalone Lip Gloss, the workflow is simpler:
+//
+// hasDarkBG := lipgloss.HasDarkBackground(os.Stdin, os.Stdout)
+// lightDark := lipgloss.LightDark(hasDarkBG)
+// red, blue := lipgloss.Color("#ff0000"), lipgloss.Color("#0000ff")
+// myHotColor := lightDark(red, blue)
+func LightDark(isDark bool) LightDarkFunc {
+ return func(light, dark color.Color) color.Color {
+ if isDark {
+ return dark
+ }
+ return light
+ }
+}
+
+// isDarkColor returns whether the given color is dark (based on the luminance
+// portion of the color as interpreted as HSL).
+//
+// Example usage:
+//
+// color := lipgloss.Color("#0000ff")
+// if lipgloss.isDarkColor(color) {
+// fmt.Println("It's dark! I love darkness!")
+// } else {
+// fmt.Println("It's light! Cover your eyes!")
+// }
+func isDarkColor(c color.Color) bool {
+ col, ok := colorful.MakeColor(c)
+ if !ok {
+ return true
+ }
+
+ _, _, l := col.Hsl()
+ return l < 0.5 //nolint:mnd
+}
+
+// CompleteFunc is a function that returns the appropriate color based on the
+// given color profile.
+//
+// Example usage:
+//
+// p := colorprofile.Detect(os.Stderr, os.Environ())
+// complete := lipgloss.Complete(p)
+// color := complete(
+// lipgloss.Color(1), // ANSI
+// lipgloss.Color(124), // ANSI256
+// lipgloss.Color("#ff34ac"), // TrueColor
+// )
+// fmt.Println("Ooh, pretty color: ", color)
+//
+// For more info see [Complete].
+type CompleteFunc func(ansi, ansi256, truecolor color.Color) color.Color
+
+// Complete returns a function that will return the appropriate color based on
+// the given color profile.
+//
+// Example usage:
+//
+// p := colorprofile.Detect(os.Stderr, os.Environ())
+// complete := lipgloss.Complete(p)
+// color := complete(
+// lipgloss.Color(1), // ANSI
+// lipgloss.Color(124), // ANSI256
+// lipgloss.Color("#ff34ac"), // TrueColor
+// )
+// fmt.Println("Ooh, pretty color: ", color)
+func Complete(p colorprofile.Profile) CompleteFunc {
+ return func(ansi, ansi256, truecolor color.Color) color.Color {
+ switch p { //nolint:exhaustive
+ case colorprofile.ANSI:
+ return ansi
+ case colorprofile.ANSI256:
+ return ansi256
+ case colorprofile.TrueColor:
+ return truecolor
+ }
+ return noColor
+ }
+}
+
+// ensureNotTransparent ensures that the alpha value of a color is not 0, and if
+// it is, we will set it to 1. This is useful for when we are converting from
+// RGB -> RGBA, and the alpha value is lost in the conversion for gradient purposes.
+func ensureNotTransparent(c color.Color) color.Color {
+ _, _, _, a := c.RGBA()
+ if a == 0 {
+ return Alpha(c, 1)
+ }
+ return c
+}
+
+// Alpha adjusts the alpha value of a color using a 0-1 (clamped) float scale
+// 0 = transparent, 1 = opaque.
+func Alpha(c color.Color, alpha float64) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ r, g, b, _ := c.RGBA()
+ return color.RGBA{
+ R: uint8(min(255, float64(r>>8))),
+ G: uint8(min(255, float64(g>>8))),
+ B: uint8(min(255, float64(b>>8))),
+ A: uint8(clamp(alpha, 0, 1) * 255),
+ }
+}
+
+// Complementary returns the complementary color (180° away on color wheel) of
+// the given color. This is useful for creating a contrasting color.
+func Complementary(c color.Color) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ // Offset hue by 180°.
+ cf, _ := colorful.MakeColor(ensureNotTransparent(c))
+
+ h, s, v := cf.Hsv()
+ h += 180
+ if h >= 360 {
+ h -= 360
+ } else if h < 0 {
+ h += 360
+ }
+
+ return colorful.Hsv(h, s, v).Clamped()
+}
+
+// Darken takes a color and makes it darker by a specific percentage (0-1, clamped).
+func Darken(c color.Color, percent float64) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ mult := 1.0 - clamp(percent, 0, 1)
+
+ r, g, b, a := c.RGBA()
+ return color.RGBA{
+ R: uint8(float64(r>>8) * mult),
+ G: uint8(float64(g>>8) * mult),
+ B: uint8(float64(b>>8) * mult),
+ A: uint8(min(255, float64(a>>8))),
+ }
+}
+
+// Lighten makes a color lighter by a specific percentage (0-1, clamped).
+func Lighten(c color.Color, percent float64) color.Color {
+ if c == nil {
+ return nil
+ }
+
+ add := 255 * (clamp(percent, 0, 1))
+
+ r, g, b, a := c.RGBA()
+ return color.RGBA{
+ R: uint8(min(255, float64(r>>8)+add)),
+ G: uint8(min(255, float64(g>>8)+add)),
+ B: uint8(min(255, float64(b>>8)+add)),
+ A: uint8(min(255, float64(a>>8))),
+ }
+}
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/get.go b/tools/vendor/charm.land/lipgloss/v2/get.go
similarity index 80%
rename from tools/vendor/github.com/charmbracelet/lipgloss/get.go
rename to tools/vendor/charm.land/lipgloss/v2/get.go
index 422b4ce95..d1fe1d669 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/get.go
+++ b/tools/vendor/charm.land/lipgloss/v2/get.go
@@ -1,6 +1,7 @@
package lipgloss
import (
+ "image/color"
"strings"
"github.com/charmbracelet/x/ansi"
@@ -20,7 +21,19 @@ func (s Style) GetItalic() bool {
// GetUnderline returns the style's underline value. If no value is set false is
// returned.
func (s Style) GetUnderline() bool {
- return s.getAsBool(underlineKey, false)
+ return s.ul != UnderlineNone
+}
+
+// GetUnderlineStyle returns the style's underline style. If no value is set
+// UnderlineNone is returned.
+func (s Style) GetUnderlineStyle() Underline {
+ return s.ul
+}
+
+// GetUnderlineColor returns the style's underline color. If no value is set
+// NoColor{} is returned.
+func (s Style) GetUnderlineColor() color.Color {
+ return s.getAsColor(underlineColorKey)
}
// GetStrikethrough returns the style's strikethrough value. If no value is set false
@@ -49,13 +62,13 @@ func (s Style) GetFaint() bool {
// GetForeground returns the style's foreground color. If no value is set
// NoColor{} is returned.
-func (s Style) GetForeground() TerminalColor {
+func (s Style) GetForeground() color.Color {
return s.getAsColor(foregroundKey)
}
// GetBackground returns the style's background color. If no value is set
// NoColor{} is returned.
-func (s Style) GetBackground() TerminalColor {
+func (s Style) GetBackground() color.Color {
return s.getAsColor(backgroundKey)
}
@@ -134,6 +147,16 @@ func (s Style) GetPaddingLeft() int {
return s.getAsInt(paddingLeftKey)
}
+// GetPaddingChar returns the style's padding character. If no value is set a
+// space is returned.
+func (s Style) GetPaddingChar() rune {
+ char := s.getAsRune(paddingCharKey)
+ if char == 0 {
+ return ' '
+ }
+ return char
+}
+
// GetHorizontalPadding returns the style's left and right padding. Unset
// values are measured as 0.
func (s Style) GetHorizontalPadding() int {
@@ -185,6 +208,16 @@ func (s Style) GetMarginLeft() int {
return s.getAsInt(marginLeftKey)
}
+// GetMarginChar returns the style's padding character. If no value is set a
+// space is returned.
+func (s Style) GetMarginChar() rune {
+ char := s.getAsRune(marginCharKey)
+ if char == 0 {
+ return ' '
+ }
+ return char
+}
+
// GetHorizontalMargins returns the style's left and right margins. Unset
// values are measured as 0.
func (s Style) GetHorizontalMargins() int {
@@ -241,49 +274,61 @@ func (s Style) GetBorderLeft() bool {
// GetBorderTopForeground returns the style's border top foreground color. If
// no value is set NoColor{} is returned.
-func (s Style) GetBorderTopForeground() TerminalColor {
+func (s Style) GetBorderTopForeground() color.Color {
return s.getAsColor(borderTopForegroundKey)
}
// GetBorderRightForeground returns the style's border right foreground color.
// If no value is set NoColor{} is returned.
-func (s Style) GetBorderRightForeground() TerminalColor {
+func (s Style) GetBorderRightForeground() color.Color {
return s.getAsColor(borderRightForegroundKey)
}
// GetBorderBottomForeground returns the style's border bottom foreground
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderBottomForeground() TerminalColor {
+func (s Style) GetBorderBottomForeground() color.Color {
return s.getAsColor(borderBottomForegroundKey)
}
// GetBorderLeftForeground returns the style's border left foreground
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderLeftForeground() TerminalColor {
+func (s Style) GetBorderLeftForeground() color.Color {
return s.getAsColor(borderLeftForegroundKey)
}
+// GetBorderForegroundBlend returns the style's border blend foreground
+// colors. If no value is set, nil is returned.
+func (s Style) GetBorderForegroundBlend() []color.Color {
+ return s.getAsColors(borderForegroundBlendKey)
+}
+
+// GetBorderForegroundBlendOffset returns the style's border blend offset. If no
+// value is set, 0 is returned.
+func (s Style) GetBorderForegroundBlendOffset() int {
+ return s.getAsInt(borderForegroundBlendOffsetKey)
+}
+
// GetBorderTopBackground returns the style's border top background color. If
// no value is set NoColor{} is returned.
-func (s Style) GetBorderTopBackground() TerminalColor {
+func (s Style) GetBorderTopBackground() color.Color {
return s.getAsColor(borderTopBackgroundKey)
}
// GetBorderRightBackground returns the style's border right background color.
// If no value is set NoColor{} is returned.
-func (s Style) GetBorderRightBackground() TerminalColor {
+func (s Style) GetBorderRightBackground() color.Color {
return s.getAsColor(borderRightBackgroundKey)
}
// GetBorderBottomBackground returns the style's border bottom background
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderBottomBackground() TerminalColor {
+func (s Style) GetBorderBottomBackground() color.Color {
return s.getAsColor(borderBottomBackgroundKey)
}
// GetBorderLeftBackground returns the style's border left background
// color. If no value is set NoColor{} is returned.
-func (s Style) GetBorderLeftBackground() TerminalColor {
+func (s Style) GetBorderLeftBackground() color.Color {
return s.getAsColor(borderLeftBackgroundKey)
}
@@ -300,7 +345,10 @@ func (s Style) GetBorderTopWidth() int {
// runes of varying widths, the widest rune is returned. If no border exists on
// the top edge, 0 is returned.
func (s Style) GetBorderTopSize() int {
- if !s.getAsBool(borderTopKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderTopKey, false) {
return 0
}
return s.getBorderStyle().GetTopSize()
@@ -310,7 +358,10 @@ func (s Style) GetBorderTopSize() int {
// runes of varying widths, the widest rune is returned. If no border exists on
// the left edge, 0 is returned.
func (s Style) GetBorderLeftSize() int {
- if !s.getAsBool(borderLeftKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderLeftKey, false) {
return 0
}
return s.getBorderStyle().GetLeftSize()
@@ -320,7 +371,10 @@ func (s Style) GetBorderLeftSize() int {
// contain runes of varying widths, the widest rune is returned. If no border
// exists on the left edge, 0 is returned.
func (s Style) GetBorderBottomSize() int {
- if !s.getAsBool(borderBottomKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderBottomKey, false) {
return 0
}
return s.getBorderStyle().GetBottomSize()
@@ -330,7 +384,10 @@ func (s Style) GetBorderBottomSize() int {
// contain runes of varying widths, the widest rune is returned. If no border
// exists on the right edge, 0 is returned.
func (s Style) GetBorderRightSize() int {
- if !s.getAsBool(borderRightKey, false) && !s.implicitBorders() {
+ if s.isBorderStyleSetWithoutSides() {
+ return 1
+ }
+ if !s.getAsBool(borderRightKey, false) {
return 0
}
return s.getBorderStyle().GetRightSize()
@@ -414,11 +471,36 @@ func (s Style) GetTransform() func(string) string {
return s.getAsTransform(transformKey)
}
+// GetHyperlink returns the hyperlink along with its parameters. If no
+// hyperlink is set, empty strings are returned.
+func (s Style) GetHyperlink() (link, params string) {
+ if s.isSet(linkKey) {
+ link = s.link
+ }
+ if s.isSet(linkParamsKey) {
+ params = s.linkParams
+ }
+ return
+}
+
// Returns whether or not the given property is set.
func (s Style) isSet(k propKey) bool {
return s.props.has(k)
}
+func (s Style) getAsRune(k propKey) rune {
+ if !s.isSet(k) {
+ return 0
+ }
+ switch k { //nolint:exhaustive
+ case paddingCharKey:
+ return s.paddingChar
+ case marginCharKey:
+ return s.marginChar
+ }
+ return 0
+}
+
func (s Style) getAsBool(k propKey, defaultVal bool) bool {
if !s.isSet(k) {
return defaultVal
@@ -426,12 +508,25 @@ func (s Style) getAsBool(k propKey, defaultVal bool) bool {
return s.attrs&int(k) != 0
}
-func (s Style) getAsColor(k propKey) TerminalColor {
+func (s Style) getAsColors(k propKey) (colors []color.Color) {
+ if !s.isSet(k) {
+ return nil
+ }
+
+ switch k { //nolint:exhaustive
+ case borderForegroundBlendKey:
+ return s.borderBlendFgColor
+ }
+
+ return nil
+}
+
+func (s Style) getAsColor(k propKey) color.Color {
if !s.isSet(k) {
return noColor
}
- var c TerminalColor
+ var c color.Color
switch k { //nolint:exhaustive
case foregroundKey:
c = s.fgColor
@@ -455,6 +550,8 @@ func (s Style) getAsColor(k propKey) TerminalColor {
c = s.borderBottomBgColor
case borderLeftBackgroundKey:
c = s.borderLeftBgColor
+ case underlineColorKey:
+ c = s.ulColor
}
if c != nil {
@@ -489,6 +586,8 @@ func (s Style) getAsInt(k propKey) int {
return s.marginBottom
case marginLeftKey:
return s.marginLeft
+ case borderForegroundBlendOffsetKey:
+ return s.borderForegroundBlendOffset
case maxWidthKey:
return s.maxWidth
case maxHeightKey:
@@ -519,20 +618,6 @@ func (s Style) getBorderStyle() Border {
return s.borderStyle
}
-// Returns whether or not the style has implicit borders. This happens when
-// a border style has been set but no border sides have been explicitly turned
-// on or off.
-func (s Style) implicitBorders() bool {
- var (
- borderStyle = s.getBorderStyle()
- topSet = s.isSet(borderTopKey)
- rightSet = s.isSet(borderRightKey)
- bottomSet = s.isSet(borderBottomKey)
- leftSet = s.isSet(borderLeftKey)
- )
- return borderStyle != noBorder && !(topSet || rightSet || bottomSet || leftSet)
-}
-
func (s Style) getAsTransform(propKey) func(string) string {
if !s.isSet(transformKey) {
return nil
@@ -543,6 +628,8 @@ func (s Style) getAsTransform(propKey) func(string) string {
// Split a string into lines, additionally returning the size of the widest
// line.
func getLines(s string) (lines []string, widest int) {
+ s = strings.ReplaceAll(s, "\t", " ")
+ s = strings.ReplaceAll(s, "\r\n", "\n")
lines = strings.Split(s, "\n")
for _, l := range lines {
@@ -554,3 +641,17 @@ func getLines(s string) (lines []string, widest int) {
return lines, widest
}
+
+// isBorderStyleSetWithoutSides returns true if the border style is set but no
+// sides are set. This is used to determine if the border should be rendered by
+// default.
+func (s Style) isBorderStyleSetWithoutSides() bool {
+ var (
+ border = s.getBorderStyle()
+ topSet = s.isSet(borderTopKey)
+ rightSet = s.isSet(borderRightKey)
+ bottomSet = s.isSet(borderBottomKey)
+ leftSet = s.isSet(borderLeftKey)
+ )
+ return border != noBorder && !(topSet || rightSet || bottomSet || leftSet) //nolint:staticcheck
+}
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/join.go b/tools/vendor/charm.land/lipgloss/v2/join.go
similarity index 97%
rename from tools/vendor/github.com/charmbracelet/lipgloss/join.go
rename to tools/vendor/charm.land/lipgloss/v2/join.go
index b0a23a546..349ae552f 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/join.go
+++ b/tools/vendor/charm.land/lipgloss/v2/join.go
@@ -60,7 +60,7 @@ func JoinHorizontal(pos Position, strs ...string) string {
extraLines := make([]string, maxHeight-len(blocks[i]))
- switch pos { //nolint:exhaustive
+ switch pos {
case Top:
blocks[i] = append(blocks[i], extraLines...)
@@ -139,7 +139,7 @@ func JoinVertical(pos Position, strs ...string) string {
for j, line := range block {
w := maxWidth - ansi.StringWidth(line)
- switch pos { //nolint:exhaustive
+ switch pos {
case Left:
b.WriteString(line)
b.WriteString(strings.Repeat(" ", w))
@@ -165,7 +165,7 @@ func JoinVertical(pos Position, strs ...string) string {
// Write a newline as long as we're not on the last line of the
// last block.
- if !(i == len(blocks)-1 && j == len(block)-1) {
+ if !(i == len(blocks)-1 && j == len(block)-1) { //nolint:staticcheck
b.WriteRune('\n')
}
}
diff --git a/tools/vendor/charm.land/lipgloss/v2/layer.go b/tools/vendor/charm.land/lipgloss/v2/layer.go
new file mode 100644
index 000000000..e30d1ef2a
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/layer.go
@@ -0,0 +1,327 @@
+package lipgloss
+
+import (
+ "fmt"
+ "image"
+ "slices"
+
+ uv "github.com/charmbracelet/ultraviolet"
+)
+
+// Layer represents a visual layer with content and positioning. It's a pure
+// data structure that defines the layer hierarchy without any computation.
+type Layer struct {
+ id string
+ content string
+ width, height int
+ x, y, z int
+ layers []*Layer
+}
+
+// NewLayer creates a new [Layer] with the given content and optional child layers.
+func NewLayer(content string, layers ...*Layer) *Layer {
+ l := &Layer{
+ content: content,
+ }
+ l.AddLayers(layers...)
+ return l
+}
+
+// GetContent returns the content of the Layer.
+func (l *Layer) GetContent() string {
+ return l.content
+}
+
+// Width returns the width of the Layer.
+func (l *Layer) Width() int {
+ return l.width
+}
+
+// Height returns the height of the Layer.
+func (l *Layer) Height() int {
+ return l.height
+}
+
+// GetID returns the ID of the Layer.
+func (l *Layer) GetID() string {
+ return l.id
+}
+
+// ID sets the ID of the Layer.
+func (l *Layer) ID(id string) *Layer {
+ l.id = id
+ return l
+}
+
+// X sets the x-coordinate of the Layer relative to its parent.
+func (l *Layer) X(x int) *Layer {
+ l.x = x
+ return l
+}
+
+// Y sets the y-coordinate of the Layer relative to its parent.
+func (l *Layer) Y(y int) *Layer {
+ l.y = y
+ return l
+}
+
+// Z sets the z-index of the Layer relative to its parent.
+func (l *Layer) Z(z int) *Layer {
+ l.z = z
+ return l
+}
+
+// GetX returns the x-coordinate of the Layer relative to its parent.
+func (l *Layer) GetX() int {
+ return l.x
+}
+
+// GetY returns the y-coordinate of the Layer relative to its parent.
+func (l *Layer) GetY() int {
+ return l.y
+}
+
+// GetZ returns the z-index of the Layer relative to its parent.
+func (l *Layer) GetZ() int {
+ return l.z
+}
+
+// AddLayers adds child layers to the Layer.
+func (l *Layer) AddLayers(layers ...*Layer) *Layer {
+ for i, layer := range layers {
+ if layer == nil {
+ panic(fmt.Sprintf("layer at index %d is nil", i))
+ }
+ l.layers = append(l.layers, layer)
+ }
+ area := l.boundsWithOffset(0, 0)
+ l.width = area.Dx()
+ l.height = area.Dy()
+ return l
+}
+
+// GetLayer returns a descendant layer by its ID, or nil if not found.
+// Layers with empty IDs are skipped.
+func (l *Layer) GetLayer(id string) *Layer {
+ if id == "" {
+ return nil
+ }
+ if l.id == id {
+ return l
+ }
+ for _, child := range l.layers {
+ if found := child.GetLayer(id); found != nil {
+ return found
+ }
+ }
+ return nil
+}
+
+// MaxZ returns the maximum z-index among this layer and all its descendants.
+func (l *Layer) MaxZ() int {
+ maxZ := l.z
+ for _, child := range l.layers {
+ childMaxZ := child.MaxZ()
+ if childMaxZ > maxZ {
+ maxZ = childMaxZ
+ }
+ }
+ return maxZ
+}
+
+// boundsWithOffset calculates bounds with parent offset applied.
+func (l *Layer) boundsWithOffset(parentX, parentY int) image.Rectangle {
+ absX := l.x + parentX
+ absY := l.y + parentY
+
+ width, height := Width(l.content), Height(l.content)
+ bounds := image.Rectangle{
+ Min: image.Pt(absX, absY),
+ Max: image.Pt(absX+width, absY+height),
+ }
+
+ for _, child := range l.layers {
+ bounds = bounds.Union(child.boundsWithOffset(absX, absY))
+ }
+
+ return bounds
+}
+
+var _ uv.Drawable = (*Layer)(nil)
+
+// Draw draws the content of the layer on the screen at the specified area.
+func (l *Layer) Draw(scr uv.Screen, area uv.Rectangle) {
+ content := uv.NewStyledString(l.content)
+ content.Draw(scr, area)
+}
+
+// LayerHit represents the result of a hit test on a [Layer].
+type LayerHit struct {
+ id string
+ layer *Layer
+ bounds image.Rectangle
+}
+
+// Empty returns true if the LayerHit represents no hit.
+func (lh LayerHit) Empty() bool {
+ return lh.layer == nil
+}
+
+// ID returns the ID of the hit Layer.
+func (lh LayerHit) ID() string {
+ return lh.id
+}
+
+// Layer returns the layer that was hit.
+func (lh LayerHit) Layer() *Layer {
+ return lh.layer
+}
+
+// Bounds returns the bounds of the LayerHit.
+func (lh LayerHit) Bounds() image.Rectangle {
+ return lh.bounds
+}
+
+// Compositor manages the composition of layers. It flattens a layer hierarchy
+// once and provides efficient drawing and hit testing operations. All computation
+// related to layers happens in the Compositor.
+type Compositor struct {
+ root *Layer
+ layers []compositeLayer
+ index map[string]*Layer
+ bounds image.Rectangle
+}
+
+// compositeLayer holds a flattened layer with its calculated absolute position and bounds.
+type compositeLayer struct {
+ layer *Layer
+ absX int
+ absY int
+ bounds image.Rectangle
+}
+
+// NewCompositor creates a new Compositor with an internal root layer. Optional
+// layers can be provided which will be added as children of the root. The layer
+// hierarchy is flattened and sorted by z-index for efficient rendering and hit testing.
+func NewCompositor(layers ...*Layer) *Compositor {
+ root := NewLayer("")
+ root.AddLayers(layers...)
+ c := &Compositor{
+ root: root,
+ index: make(map[string]*Layer),
+ }
+ c.flatten()
+ return c
+}
+
+// AddLayers adds layers to the compositor's root and refreshes the internal state.
+func (c *Compositor) AddLayers(layers ...*Layer) *Compositor {
+ c.root.AddLayers(layers...)
+ c.flatten()
+ return c
+}
+
+// flatten builds the internal flattened layer list and calculates overall bounds.
+func (c *Compositor) flatten() {
+ c.layers = nil
+ c.index = make(map[string]*Layer)
+ c.flattenRecursive(c.root, 0, 0)
+
+ // Sort by absolute z-index (lowest to highest for drawing)
+ slices.SortFunc(c.layers, func(a, b compositeLayer) int {
+ return a.layer.z - b.layer.z
+ })
+
+ // Calculate overall bounds
+ if len(c.layers) > 0 {
+ c.bounds = c.layers[0].bounds
+ for i := 1; i < len(c.layers); i++ {
+ c.bounds = c.bounds.Union(c.layers[i].bounds)
+ }
+ }
+}
+
+// flattenRecursive recursively collects all layers with their absolute positions.
+func (c *Compositor) flattenRecursive(layer *Layer, parentX, parentY int) {
+ absX := layer.x + parentX
+ absY := layer.y + parentY
+
+ width, height := Width(layer.content), Height(layer.content)
+ bounds := image.Rectangle{
+ Min: image.Pt(absX, absY),
+ Max: image.Pt(absX+width, absY+height),
+ }
+
+ c.layers = append(c.layers, compositeLayer{
+ layer: layer,
+ absX: absX,
+ absY: absY,
+ bounds: bounds,
+ })
+
+ // Index layer by ID if it has one
+ if layer.id != "" {
+ c.index[layer.id] = layer
+ }
+
+ for _, child := range layer.layers {
+ c.flattenRecursive(child, absX, absY)
+ }
+}
+
+// Bounds returns the overall bounds of all layers in the compositor.
+func (c *Compositor) Bounds() image.Rectangle {
+ return c.bounds
+}
+
+// Draw draws all layers onto the given [uv.Screen] in z-index order.
+func (c *Compositor) Draw(scr uv.Screen, area image.Rectangle) {
+ for _, cl := range c.layers {
+ if cl.bounds.Overlaps(area) {
+ cl.layer.Draw(scr, cl.bounds)
+ }
+ }
+}
+
+// Hit performs a hit test at the given (x, y) coordinates. If a layer is hit,
+// it returns the ID of the top-most layer at that point. Layers with empty IDs
+// are ignored. If no layer is hit, it returns an empty [LayerHit].
+func (c *Compositor) Hit(x, y int) LayerHit {
+ var hit LayerHit
+ pt := image.Pt(x, y)
+ // Check from highest z to lowest (reverse order)
+ for i := len(c.layers) - 1; i >= 0; i-- {
+ cl := c.layers[i]
+ if cl.layer.id != "" && pt.In(cl.bounds) {
+ hit.id = cl.layer.id
+ hit.layer = cl.layer
+ hit.bounds = cl.bounds
+ return hit
+ }
+ }
+ return hit
+}
+
+// GetLayer returns a layer by its ID, or nil if not found.
+// Layers with empty IDs are not indexed and cannot be retrieved.
+func (c *Compositor) GetLayer(id string) *Layer {
+ if id == "" {
+ return nil
+ }
+ return c.index[id]
+}
+
+// Refresh re-flattens the layer hierarchy. Call this after modifying the layer
+// tree structure or positions to update the compositor's internal state.
+func (c *Compositor) Refresh() {
+ c.flatten()
+}
+
+// Render renders the compositor into a styled string. This is a helper
+// function that creates a temporary canvas, draws the compositor onto it, and
+// returns the resulting string.
+func (c *Compositor) Render() string {
+ width, height := c.bounds.Dx(), c.bounds.Dy()
+ canvas := NewCanvas(width, height)
+ return canvas.Compose(c).Render()
+}
diff --git a/tools/vendor/charm.land/lipgloss/v2/lipgloss.go b/tools/vendor/charm.land/lipgloss/v2/lipgloss.go
new file mode 100644
index 000000000..3fb4e6f26
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/lipgloss.go
@@ -0,0 +1,3 @@
+// Package lipgloss provides style definitions for nice terminal layouts. Built
+// with TUIs in mind.
+package lipgloss
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/position.go b/tools/vendor/charm.land/lipgloss/v2/position.go
similarity index 69%
rename from tools/vendor/github.com/charmbracelet/lipgloss/position.go
rename to tools/vendor/charm.land/lipgloss/v2/position.go
index 185f5af3b..cea67763f 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/position.go
+++ b/tools/vendor/charm.land/lipgloss/v2/position.go
@@ -34,26 +34,13 @@ const (
// Place places a string or text block vertically in an unstyled box of a given
// width or height.
func Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
- return renderer.Place(width, height, hPos, vPos, str, opts...)
-}
-
-// Place places a string or text block vertically in an unstyled box of a given
-// width or height.
-func (r *Renderer) Place(width, height int, hPos, vPos Position, str string, opts ...WhitespaceOption) string {
- return r.PlaceVertical(height, vPos, r.PlaceHorizontal(width, hPos, str, opts...), opts...)
+ return PlaceVertical(height, vPos, PlaceHorizontal(width, hPos, str, opts...), opts...)
}
// PlaceHorizontal places a string or text block horizontally in an unstyled
// block of a given width. If the given width is shorter than the max width of
// the string (measured by its longest line) this will be a noop.
func PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
- return renderer.PlaceHorizontal(width, pos, str, opts...)
-}
-
-// PlaceHorizontal places a string or text block horizontally in an unstyled
-// block of a given width. If the given width is shorter than the max width of
-// the string (measured by its longest line) this will be a noöp.
-func (r *Renderer) PlaceHorizontal(width int, pos Position, str string, opts ...WhitespaceOption) string {
lines, contentWidth := getLines(str)
gap := width - contentWidth
@@ -61,14 +48,14 @@ func (r *Renderer) PlaceHorizontal(width int, pos Position, str string, opts ...
return str
}
- ws := newWhitespace(r, opts...)
+ ws := newWhitespace(opts...)
var b strings.Builder
for i, l := range lines {
// Is this line shorter than the longest line?
short := max(0, contentWidth-ansi.StringWidth(l))
- switch pos { //nolint:exhaustive
+ switch pos {
case Left:
b.WriteString(l)
b.WriteString(ws.render(gap + short))
@@ -101,13 +88,6 @@ func (r *Renderer) PlaceHorizontal(width int, pos Position, str string, opts ...
// of a given height. If the given height is shorter than the height of the
// string (measured by its newlines) then this will be a noop.
func PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
- return renderer.PlaceVertical(height, pos, str, opts...)
-}
-
-// PlaceVertical places a string or text block vertically in an unstyled block
-// of a given height. If the given height is shorter than the height of the
-// string (measured by its newlines) then this will be a noöp.
-func (r *Renderer) PlaceVertical(height int, pos Position, str string, opts ...WhitespaceOption) string {
contentHeight := strings.Count(str, "\n") + 1
gap := height - contentHeight
@@ -115,17 +95,17 @@ func (r *Renderer) PlaceVertical(height int, pos Position, str string, opts ...W
return str
}
- ws := newWhitespace(r, opts...)
+ ws := newWhitespace(opts...)
_, width := getLines(str)
emptyLine := ws.render(width)
b := strings.Builder{}
- switch pos { //nolint:exhaustive
+ switch pos {
case Top:
b.WriteString(str)
b.WriteRune('\n')
- for i := 0; i < gap; i++ {
+ for i := range gap {
b.WriteString(emptyLine)
if i < gap-1 {
b.WriteRune('\n')
@@ -144,7 +124,7 @@ func (r *Renderer) PlaceVertical(height int, pos Position, str string, opts ...W
b.WriteString(strings.Repeat(emptyLine+"\n", top))
b.WriteString(str)
- for i := 0; i < bottom; i++ {
+ for range bottom {
b.WriteRune('\n')
b.WriteString(emptyLine)
}
diff --git a/tools/vendor/charm.land/lipgloss/v2/query.go b/tools/vendor/charm.land/lipgloss/v2/query.go
new file mode 100644
index 000000000..96cd5b945
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/query.go
@@ -0,0 +1,92 @@
+package lipgloss
+
+import (
+ "fmt"
+ "image/color"
+ "os"
+ "runtime"
+
+ "github.com/charmbracelet/x/term"
+)
+
+func backgroundColor(in term.File, out term.File) (color.Color, error) {
+ state, err := term.MakeRaw(in.Fd())
+ if err != nil {
+ return nil, fmt.Errorf("error setting raw state to detect background color: %w", err)
+ }
+
+ defer term.Restore(in.Fd(), state) //nolint:errcheck
+
+ bg, err := queryBackgroundColor(in, out)
+ if err != nil {
+ return nil, err
+ }
+
+ return bg, nil
+}
+
+// BackgroundColor queries the terminal's background color. Typically, you'll
+// want to query against stdin and either stdout or stderr, depending on what
+// you're writing to.
+//
+// This function is intended for standalone Lip Gloss use only. If you're using
+// Bubble Tea, listen for tea.BackgroundColorMsg in your update function.
+func BackgroundColor(in term.File, out term.File) (bg color.Color, err error) {
+ if runtime.GOOS == "windows" { //nolint:nestif
+ // On Windows, when the input/output is redirected or piped, we need to
+ // open the console explicitly.
+ // See https://learn.microsoft.com/en-us/windows/console/getstdhandle#remarks
+ if !term.IsTerminal(in.Fd()) {
+ f, err := os.OpenFile("CONIN$", os.O_RDWR, 0o644) //nolint:gosec
+ if err != nil {
+ return nil, fmt.Errorf("error opening CONIN$: %w", err)
+ }
+ in = f
+ }
+ if !term.IsTerminal(out.Fd()) {
+ f, err := os.OpenFile("CONOUT$", os.O_RDWR, 0o644) //nolint:gosec
+ if err != nil {
+ return nil, fmt.Errorf("error opening CONOUT$: %w", err)
+ }
+ out = f
+ }
+ return backgroundColor(in, out)
+ }
+
+ // NOTE: On Unix, one of the given files must be a tty.
+ if !term.IsTerminal(in.Fd()) || !term.IsTerminal(out.Fd()) {
+ return nil, fmt.Errorf("input/output is not a terminal")
+ }
+ for _, f := range []term.File{in, out} {
+ if bg, err = backgroundColor(f, f); err == nil {
+ return bg, nil
+ }
+ }
+
+ return bg, err
+}
+
+// HasDarkBackground detects whether the terminal has a light or dark
+// background.
+//
+// Typically, you'll want to query against stdin and either stdout or stderr
+// depending on what you're writing to.
+//
+// hasDarkBG := HasDarkBackground(os.Stdin, os.Stdout)
+// lightDark := LightDark(hasDarkBG)
+// myHotColor := lightDark("#ff0000", "#0000ff")
+//
+// This is intended for use in standalone Lip Gloss only. In Bubble Tea, listen
+// for tea.BackgroundColorMsg in your Update function.
+//
+// case tea.BackgroundColorMsg:
+// hasDarkBackground = msg.IsDark()
+//
+// By default, this function will return true if it encounters an error.
+func HasDarkBackground(in term.File, out term.File) bool {
+ bg, err := BackgroundColor(in, out)
+ if err != nil || bg == nil {
+ return true
+ }
+ return isDarkColor(bg)
+}
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/ranges.go b/tools/vendor/charm.land/lipgloss/v2/ranges.go
similarity index 75%
rename from tools/vendor/github.com/charmbracelet/lipgloss/ranges.go
rename to tools/vendor/charm.land/lipgloss/v2/ranges.go
index d17169987..bb209f0ea 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/ranges.go
+++ b/tools/vendor/charm.land/lipgloss/v2/ranges.go
@@ -6,9 +6,8 @@ import (
"github.com/charmbracelet/x/ansi"
)
-// StyleRanges allows to, given a string, style ranges of it differently.
-// The function will take into account existing styles.
-// Ranges should not overlap.
+// StyleRanges applying styling to ranges in a string. Existing styles will be
+// taken into account. Ranges should not overlap.
func StyleRanges(s string, ranges ...Range) string {
if len(ranges) == 0 {
return s
@@ -36,12 +35,13 @@ func StyleRanges(s string, ranges ...Range) string {
return buf.String()
}
-// NewRange returns a range that can be used with [StyleRanges].
+// NewRange returns a range and style that can be used with [StyleRanges].
func NewRange(start, end int, style Style) Range {
return Range{start, end, style}
}
-// Range to be used with [StyleRanges].
+// Range is a range of text and associated styling to be used with
+// [StyleRanges].
type Range struct {
Start, End int
Style Style
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/runes.go b/tools/vendor/charm.land/lipgloss/v2/runes.go
similarity index 100%
rename from tools/vendor/github.com/charmbracelet/lipgloss/runes.go
rename to tools/vendor/charm.land/lipgloss/v2/runes.go
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/set.go b/tools/vendor/charm.land/lipgloss/v2/set.go
similarity index 78%
rename from tools/vendor/github.com/charmbracelet/lipgloss/set.go
rename to tools/vendor/charm.land/lipgloss/v2/set.go
index fde38faec..f10b4538a 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/set.go
+++ b/tools/vendor/charm.land/lipgloss/v2/set.go
@@ -1,16 +1,25 @@
package lipgloss
+import (
+ "image/color"
+ "strings"
+)
+
// Set a value on the underlying rules map.
-func (s *Style) set(key propKey, value interface{}) {
+func (s *Style) set(key propKey, value any) {
// We don't allow negative integers on any of our other values, so just keep
// them at zero or above. We could use uints instead, but the
// conversions are a little tedious, so we're sticking with ints for
// sake of usability.
- switch key { //nolint:exhaustive
+ switch key {
case foregroundKey:
s.fgColor = colorOrNil(value)
case backgroundKey:
s.bgColor = colorOrNil(value)
+ case underlineColorKey:
+ s.ulColor = colorOrNil(value)
+ case underlineKey:
+ s.ul = value.(Underline)
case widthKey:
s.width = max(0, value.(int))
case heightKey:
@@ -27,6 +36,8 @@ func (s *Style) set(key propKey, value interface{}) {
s.paddingBottom = max(0, value.(int))
case paddingLeftKey:
s.paddingLeft = max(0, value.(int))
+ case paddingCharKey:
+ s.paddingChar = value.(rune)
case marginTopKey:
s.marginTop = max(0, value.(int))
case marginRightKey:
@@ -37,6 +48,8 @@ func (s *Style) set(key propKey, value interface{}) {
s.marginLeft = max(0, value.(int))
case marginBackgroundKey:
s.marginBgColor = colorOrNil(value)
+ case marginCharKey:
+ s.marginChar = value.(rune)
case borderStyleKey:
s.borderStyle = value.(Border)
case borderTopForegroundKey:
@@ -47,6 +60,10 @@ func (s *Style) set(key propKey, value interface{}) {
s.borderBottomFgColor = colorOrNil(value)
case borderLeftForegroundKey:
s.borderLeftFgColor = colorOrNil(value)
+ case borderForegroundBlendKey:
+ s.borderBlendFgColor = value.([]color.Color)
+ case borderForegroundBlendOffsetKey:
+ s.borderForegroundBlendOffset = value.(int)
case borderTopBackgroundKey:
s.borderTopBgColor = colorOrNil(value)
case borderRightBackgroundKey:
@@ -65,6 +82,10 @@ func (s *Style) set(key propKey, value interface{}) {
s.tabWidth = value.(int)
case transformKey:
s.transform = value.(func(string) string)
+ case linkKey:
+ s.link = value.(string)
+ case linkParamsKey:
+ s.linkParams = value.(string)
default:
if v, ok := value.(bool); ok { //nolint:nestif
if v {
@@ -88,11 +109,15 @@ func (s *Style) set(key propKey, value interface{}) {
// setFrom sets the property from another style.
func (s *Style) setFrom(key propKey, i Style) {
- switch key { //nolint:exhaustive
+ switch key {
case foregroundKey:
s.set(foregroundKey, i.fgColor)
case backgroundKey:
s.set(backgroundKey, i.bgColor)
+ case underlineColorKey:
+ s.set(underlineColorKey, i.ulColor)
+ case underlineKey:
+ s.set(underlineKey, i.ul)
case widthKey:
s.set(widthKey, i.width)
case heightKey:
@@ -109,6 +134,8 @@ func (s *Style) setFrom(key propKey, i Style) {
s.set(paddingBottomKey, i.paddingBottom)
case paddingLeftKey:
s.set(paddingLeftKey, i.paddingLeft)
+ case paddingCharKey:
+ s.set(paddingCharKey, i.paddingChar)
case marginTopKey:
s.set(marginTopKey, i.marginTop)
case marginRightKey:
@@ -119,6 +146,8 @@ func (s *Style) setFrom(key propKey, i Style) {
s.set(marginLeftKey, i.marginLeft)
case marginBackgroundKey:
s.set(marginBackgroundKey, i.marginBgColor)
+ case marginCharKey:
+ s.set(marginCharKey, i.marginChar)
case borderStyleKey:
s.set(borderStyleKey, i.borderStyle)
case borderTopForegroundKey:
@@ -129,6 +158,10 @@ func (s *Style) setFrom(key propKey, i Style) {
s.set(borderBottomForegroundKey, i.borderBottomFgColor)
case borderLeftForegroundKey:
s.set(borderLeftForegroundKey, i.borderLeftFgColor)
+ case borderForegroundBlendKey:
+ s.set(borderForegroundBlendKey, i.borderBlendFgColor)
+ case borderForegroundBlendOffsetKey:
+ s.set(borderForegroundBlendOffsetKey, i.borderForegroundBlendOffset)
case borderTopBackgroundKey:
s.set(borderTopBackgroundKey, i.borderTopBgColor)
case borderRightBackgroundKey:
@@ -151,8 +184,8 @@ func (s *Style) setFrom(key propKey, i Style) {
}
}
-func colorOrNil(c interface{}) TerminalColor {
- if c, ok := c.(TerminalColor); ok {
+func colorOrNil(c any) color.Color {
+ if c, ok := c.(color.Color); ok {
return c
}
return nil
@@ -173,9 +206,33 @@ func (s Style) Italic(v bool) Style {
// Underline sets an underline rule. By default, underlines will not be drawn on
// whitespace like margins and padding. To change this behavior set
-// UnderlineSpaces.
+// [Style.UnderlineSpaces].
func (s Style) Underline(v bool) Style {
- s.set(underlineKey, v)
+ if v {
+ return s.UnderlineStyle(UnderlineSingle)
+ }
+ return s.UnderlineStyle(UnderlineNone)
+}
+
+// UnderlineStyle sets the underline style. This can be used to set the underline
+// to be a single, double, curly, dotted, or dashed line.
+//
+// Note that not all terminal emulators support underline styles. If a style is
+// not supported, it will typically fall back to a single underline but this is
+// not guaranteed. This depends on the terminal emulator being used.
+func (s Style) UnderlineStyle(u Underline) Style {
+ s.set(underlineKey, u)
+ return s
+}
+
+// UnderlineColor sets the color of the underline. By default, the underline
+// will be the same color as the foreground.
+//
+// Note that not all terminal emulators support colored underlines. If color is
+// not supported, it might produce unexpected results. This depends on the
+// terminal emulator being used.
+func (s Style) UnderlineColor(c color.Color) Style {
+ s.set(underlineColorKey, c)
return s
}
@@ -212,19 +269,20 @@ func (s Style) Faint(v bool) Style {
//
// // Removes the foreground color
// s.Foreground(lipgloss.NoColor)
-func (s Style) Foreground(c TerminalColor) Style {
+func (s Style) Foreground(c color.Color) Style {
s.set(foregroundKey, c)
return s
}
// Background sets a background color.
-func (s Style) Background(c TerminalColor) Style {
+func (s Style) Background(c color.Color) Style {
s.set(backgroundKey, c)
return s
}
-// Width sets the width of the block before applying margins. The width, if
-// set, also determines where text will wrap.
+// Width sets the width of the block before applying margins. This means your
+// styled content will exactly equal the size set here. Text will wrap based on
+// Padding and Borders set on the style.
func (s Style) Width(i int) Style {
s.set(widthKey, i)
return s
@@ -317,6 +375,18 @@ func (s Style) PaddingBottom(i int) Style {
return s
}
+// PaddingChar sets the character used for padding. This is useful for
+// rendering blocks with a specific character, such as a space or a dot.
+// Example of using [NBSP] as padding to prevent line breaks:
+//
+// ```go
+// s := lipgloss.NewStyle().PaddingChar(lipgloss.NBSP)
+// ```
+func (s Style) PaddingChar(r rune) Style {
+ s.set(paddingCharKey, r)
+ return s
+}
+
// ColorWhitespace determines whether or not the background color should be
// applied to the padding. This is true by default as it's more than likely the
// desired and expected behavior, but it can be disabled for certain graphic
@@ -382,11 +452,18 @@ func (s Style) MarginBottom(i int) Style {
// MarginBackground sets the background color of the margin. Note that this is
// also set when inheriting from a style with a background color. In that case
// the background color on that style will set the margin color on this style.
-func (s Style) MarginBackground(c TerminalColor) Style {
+func (s Style) MarginBackground(c color.Color) Style {
s.set(marginBackgroundKey, c)
return s
}
+// MarginChar sets the character used for the margin. This is useful for
+// rendering blocks with a specific character, such as a space or a dot.
+func (s Style) MarginChar(r rune) Style {
+ s.set(marginCharKey, r)
+ return s
+}
+
// Border is shorthand for setting the border style and which sides should
// have a border at once. The variadic argument sides works as follows:
//
@@ -487,7 +564,7 @@ func (s Style) BorderLeft(v bool) Style {
// top side, followed by the right side, then the bottom, and finally the left.
//
// With more than four arguments nothing will be set.
-func (s Style) BorderForeground(c ...TerminalColor) Style {
+func (s Style) BorderForeground(c ...color.Color) Style {
if len(c) == 0 {
return s
}
@@ -506,32 +583,80 @@ func (s Style) BorderForeground(c ...TerminalColor) Style {
}
// BorderTopForeground set the foreground color for the top of the border.
-func (s Style) BorderTopForeground(c TerminalColor) Style {
+func (s Style) BorderTopForeground(c color.Color) Style {
s.set(borderTopForegroundKey, c)
return s
}
// BorderRightForeground sets the foreground color for the right side of the
// border.
-func (s Style) BorderRightForeground(c TerminalColor) Style {
+func (s Style) BorderRightForeground(c color.Color) Style {
s.set(borderRightForegroundKey, c)
return s
}
// BorderBottomForeground sets the foreground color for the bottom of the
// border.
-func (s Style) BorderBottomForeground(c TerminalColor) Style {
+func (s Style) BorderBottomForeground(c color.Color) Style {
s.set(borderBottomForegroundKey, c)
return s
}
// BorderLeftForeground sets the foreground color for the left side of the
// border.
-func (s Style) BorderLeftForeground(c TerminalColor) Style {
+func (s Style) BorderLeftForeground(c color.Color) Style {
s.set(borderLeftForegroundKey, c)
return s
}
+// BorderForegroundBlend sets the foreground colors for the border blend. At least
+// 2 colors are required to use blending, otherwise this will no-op with 0 colors,
+// and pass to BorderForeground with 1 color. This will override all other border
+// foreground colors when used.
+//
+// When providing colors, in most cases (e.g. when all border sides are enabled),
+// you will want to provide a wrapping-set of colors, so the start and end color
+// are either the same, or very similar. For example:
+//
+// lipgloss.NewStyle().BorderForegroundBlend(
+// lipgloss.Color("#00FA68"),
+// lipgloss.Color("#9900FF"),
+// lipgloss.Color("#ED5353"),
+// lipgloss.Color("#9900FF"),
+// lipgloss.Color("#00FA68"),
+// )
+func (s Style) BorderForegroundBlend(c ...color.Color) Style {
+ if len(c) == 0 {
+ return s
+ }
+
+ // Insufficient colors to use blending, pass to BorderForeground.
+ if len(c) == 1 {
+ return s.BorderForeground(c...)
+ }
+
+ s.set(borderForegroundBlendKey, c)
+ return s
+}
+
+// BorderForegroundBlendOffset sets the border blend offset cells, starting from
+// the top left corner. Value can be positive or negative, and does not need to
+// equal the dimensions of the border region. Direction (when positive) is as
+// follows ("o" is starting point):
+//
+// o -------->
+// ┌──────────┐
+// ^ │ │ |
+// | │ │ |
+// | │ │ |
+// | │ │ v
+// └──────────┘
+// <---------
+func (s Style) BorderForegroundBlendOffset(v int) Style {
+ s.set(borderForegroundBlendOffsetKey, v)
+ return s
+}
+
// BorderBackground is a shorthand function for setting all of the
// background colors of the borders at once. The arguments work as follows:
//
@@ -547,7 +672,7 @@ func (s Style) BorderLeftForeground(c TerminalColor) Style {
// top side, followed by the right side, then the bottom, and finally the left.
//
// With more than four arguments nothing will be set.
-func (s Style) BorderBackground(c ...TerminalColor) Style {
+func (s Style) BorderBackground(c ...color.Color) Style {
if len(c) == 0 {
return s
}
@@ -566,27 +691,27 @@ func (s Style) BorderBackground(c ...TerminalColor) Style {
}
// BorderTopBackground sets the background color of the top of the border.
-func (s Style) BorderTopBackground(c TerminalColor) Style {
+func (s Style) BorderTopBackground(c color.Color) Style {
s.set(borderTopBackgroundKey, c)
return s
}
// BorderRightBackground sets the background color of right side the border.
-func (s Style) BorderRightBackground(c TerminalColor) Style {
+func (s Style) BorderRightBackground(c color.Color) Style {
s.set(borderRightBackgroundKey, c)
return s
}
// BorderBottomBackground sets the background color of the bottom of the
// border.
-func (s Style) BorderBottomBackground(c TerminalColor) Style {
+func (s Style) BorderBottomBackground(c color.Color) Style {
s.set(borderBottomBackgroundKey, c)
return s
}
// BorderLeftBackground set the background color of the left side of the
// border.
-func (s Style) BorderLeftBackground(c TerminalColor) Style {
+func (s Style) BorderLeftBackground(c color.Color) Style {
s.set(borderLeftBackgroundKey, c)
return s
}
@@ -685,10 +810,18 @@ func (s Style) Transform(fn func(string) string) Style {
return s
}
-// Renderer sets the renderer for the style. This is useful for changing the
-// renderer for a style that is being used in a different context.
-func (s Style) Renderer(r *Renderer) Style {
- s.r = r
+// Hyperlink sets a hyperlink on a style. This is useful for rendering text that
+// can be clicked on in a terminal emulator that supports hyperlinks.
+//
+// Example:
+//
+// s := lipgloss.NewStyle().Hyperlink("https://charm.sh")
+// s := lipgloss.NewStyle().Hyperlink("https://charm.sh", "id=1")
+func (s Style) Hyperlink(link string, params ...string) Style {
+ s.set(linkKey, link)
+ if len(params) > 0 {
+ s.set(linkParamsKey, strings.Join(params, ":"))
+ }
return s
}
@@ -768,7 +901,7 @@ func whichSidesBool(i ...bool) (top, right, bottom, left bool, ok bool) {
// whichSidesColor is like whichSides, except it operates on a series of
// boolean values. See the comment on whichSidesInt for details on how this
// works.
-func whichSidesColor(i ...TerminalColor) (top, right, bottom, left TerminalColor, ok bool) {
+func whichSidesColor(i ...color.Color) (top, right, bottom, left color.Color, ok bool) {
switch len(i) {
case 1:
top = i[0]
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/size.go b/tools/vendor/charm.land/lipgloss/v2/size.go
similarity index 75%
rename from tools/vendor/github.com/charmbracelet/lipgloss/size.go
rename to tools/vendor/charm.land/lipgloss/v2/size.go
index e169ff5e2..e0384d035 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/size.go
+++ b/tools/vendor/charm.land/lipgloss/v2/size.go
@@ -10,10 +10,10 @@ import (
// ignored and characters wider than one cell (such as Chinese characters and
// emojis) are appropriately measured.
//
-// You should use this instead of len(string) len([]rune(string) as neither
+// You should use this instead of len(string) or len([]rune(string) as neither
// will give you accurate results.
func Width(str string) (width int) {
- for _, l := range strings.Split(str, "\n") {
+ for l := range strings.SplitSeq(str, "\n") {
w := ansi.StringWidth(l)
if w > width {
width = w
@@ -24,9 +24,8 @@ func Width(str string) (width int) {
}
// Height returns height of a string in cells. This is done simply by
-// counting \n characters. If your strings use \r\n for newlines you should
-// convert them to \n first, or simply write a separate function for measuring
-// height.
+// counting \n characters. If your output has \r\n, that sequence will be
+// replaced with a \n in [Style.Render].
func Height(str string) int {
return strings.Count(str, "\n") + 1
}
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/style.go b/tools/vendor/charm.land/lipgloss/v2/style.go
similarity index 68%
rename from tools/vendor/github.com/charmbracelet/lipgloss/style.go
rename to tools/vendor/charm.land/lipgloss/v2/style.go
index 59fa3ab21..3cd659526 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/style.go
+++ b/tools/vendor/charm.land/lipgloss/v2/style.go
@@ -1,15 +1,18 @@
package lipgloss
import (
+ "image/color"
"strings"
"unicode"
"github.com/charmbracelet/x/ansi"
- "github.com/charmbracelet/x/cellbuf"
- "github.com/muesli/termenv"
)
-const tabWidthDefault = 4
+const (
+ // NBSP is the non-breaking space rune.
+ NBSP = '\u00A0'
+ tabWidthDefault = 4
+)
// Property for a key.
type propKey int64
@@ -19,7 +22,6 @@ const (
// Boolean props come first.
boldKey propKey = 1 << iota
italicKey
- underlineKey
strikethroughKey
reverseKey
blinkKey
@@ -29,8 +31,10 @@ const (
colorWhitespaceKey
// Non-boolean props.
+ underlineKey
foregroundKey
backgroundKey
+ underlineColorKey
widthKey
heightKey
alignHorizontalKey
@@ -41,6 +45,7 @@ const (
paddingRightKey
paddingBottomKey
paddingLeftKey
+ paddingCharKey
// Margins.
marginTopKey
@@ -48,6 +53,7 @@ const (
marginBottomKey
marginLeftKey
marginBackgroundKey
+ marginCharKey
// Border runes.
borderStyleKey
@@ -63,6 +69,8 @@ const (
borderRightForegroundKey
borderBottomForegroundKey
borderLeftForegroundKey
+ borderForegroundBlendKey
+ borderForegroundBlendOffsetKey
// Border background colors.
borderTopBackgroundKey
@@ -76,6 +84,10 @@ const (
tabWidthKey
transformKey
+
+ // Hyperlink.
+ linkKey
+ linkParamsKey
)
// props is a set of properties.
@@ -96,35 +108,53 @@ func (p props) has(k propKey) bool {
return p&props(k) != 0
}
-// NewStyle returns a new, empty Style. While it's syntactic sugar for the
-// Style{} primitive, it's recommended to use this function for creating styles
-// in case the underlying implementation changes. It takes an optional string
-// value to be set as the underlying string value for this style.
-func NewStyle() Style {
- return renderer.NewStyle()
-}
+// Underline is the style of the underline.
+//
+// Caveats:
+// - Not all terminals support all underline styles.
+// - Some terminals may render unsupported styles as standard underlines.
+// - Terminal themes may affect the visibility of different underline styles.
+type Underline = ansi.Underline
+
+const (
+ // UnderlineNone is no underline.
+ UnderlineNone = ansi.UnderlineNone
+ // UnderlineSingle is a single underline. This is the default when underline is enabled.
+ UnderlineSingle = ansi.UnderlineSingle
+ // UnderlineDouble is a double underline.
+ UnderlineDouble = ansi.UnderlineDouble
+ // UnderlineCurly is a curly underline.
+ UnderlineCurly = ansi.UnderlineCurly
+ // UnderlineDotted is a dotted underline.
+ UnderlineDotted = ansi.UnderlineDotted
+ // UnderlineDashed is a dashed underline.
+ UnderlineDashed = ansi.UnderlineDashed
+)
// NewStyle returns a new, empty Style. While it's syntactic sugar for the
-// Style{} primitive, it's recommended to use this function for creating styles
-// in case the underlying implementation changes. It takes an optional string
-// value to be set as the underlying string value for this style.
-func (r *Renderer) NewStyle() Style {
- s := Style{r: r}
- return s
+// [Style]{} primitive, it's recommended to use this function for creating styles
+// in case the underlying implementation changes.
+func NewStyle() Style {
+ return Style{}
}
// Style contains a set of rules that comprise a style as a whole.
type Style struct {
- r *Renderer
props props
value string
+ // hyperlink
+ link, linkParams string
+
// we store bool props values here
attrs int
// props that have values
- fgColor TerminalColor
- bgColor TerminalColor
+ fgColor color.Color
+ bgColor color.Color
+ ulColor color.Color
+
+ ul Underline
width int
height int
@@ -136,22 +166,26 @@ type Style struct {
paddingRight int
paddingBottom int
paddingLeft int
+ paddingChar rune
marginTop int
marginRight int
marginBottom int
marginLeft int
- marginBgColor TerminalColor
-
- borderStyle Border
- borderTopFgColor TerminalColor
- borderRightFgColor TerminalColor
- borderBottomFgColor TerminalColor
- borderLeftFgColor TerminalColor
- borderTopBgColor TerminalColor
- borderRightBgColor TerminalColor
- borderBottomBgColor TerminalColor
- borderLeftBgColor TerminalColor
+ marginBgColor color.Color
+ marginChar rune
+
+ borderStyle Border
+ borderTopFgColor color.Color
+ borderRightFgColor color.Color
+ borderBottomFgColor color.Color
+ borderLeftFgColor color.Color
+ borderBlendFgColor []color.Color
+ borderForegroundBlendOffset int
+ borderTopBgColor color.Color
+ borderRightBgColor color.Color
+ borderBottomBgColor color.Color
+ borderLeftBgColor color.Color
maxWidth int
maxHeight int
@@ -167,10 +201,10 @@ func joinString(strs ...string) string {
}
// SetString sets the underlying string value for this style. To render once
-// the underlying string is set, use the Style.String. This method is
+// the underlying string is set, use the [Style.String]. This method is
// a convenience for cases when having a stringer implementation is handy, such
// as when using fmt.Sprintf. You can also simply define a style and render out
-// strings directly with Style.Render.
+// strings directly with [Style.Render].
func (s Style) SetString(strs ...string) Style {
s.value = joinString(strs...)
return s
@@ -232,9 +266,6 @@ func (s Style) Inherit(i Style) Style {
// Render applies the defined style formatting to a given string.
func (s Style) Render(strs ...string) string {
- if s.r == nil {
- s.r = renderer
- }
if s.value != "" {
strs = append([]string{s.value}, strs...)
}
@@ -242,14 +273,12 @@ func (s Style) Render(strs ...string) string {
var (
str = joinString(strs...)
- p = s.r.ColorProfile()
- te = p.String()
- teSpace = p.String()
- teWhitespace = p.String()
+ te ansi.Style
+ teSpace ansi.Style
+ teWhitespace ansi.Style
bold = s.getAsBool(boldKey, false)
italic = s.getAsBool(italicKey, false)
- underline = s.getAsBool(underlineKey, false)
strikethrough = s.getAsBool(strikethroughKey, false)
reverse = s.getAsBool(reverseKey, false)
blink = s.getAsBool(blinkKey, false)
@@ -257,7 +286,9 @@ func (s Style) Render(strs ...string) string {
fg = s.getAsColor(foregroundKey)
bg = s.getAsColor(backgroundKey)
+ ul = s.getAsColor(underlineColorKey)
+ underline = s.ul != UnderlineNone
width = s.getAsInt(widthKey)
height = s.getAsInt(heightKey)
horizontalAlign = s.getAsPosition(alignHorizontalKey)
@@ -268,6 +299,9 @@ func (s Style) Render(strs ...string) string {
bottomPadding = s.getAsInt(paddingBottomKey)
leftPadding = s.getAsInt(paddingLeftKey)
+ horizontalBorderSize = s.GetHorizontalBorderSize()
+ verticalBorderSize = s.GetVerticalBorderSize()
+
colorWhitespace = s.getAsBool(colorWhitespaceKey, true)
inline = s.getAsBool(inlineKey, false)
maxWidth = s.getAsInt(maxWidthKey)
@@ -284,6 +318,8 @@ func (s Style) Render(strs ...string) string {
useSpaceStyler = (underline && !underlineSpaces) || (strikethrough && !strikethroughSpaces) || underlineSpaces || strikethroughSpaces
transform = s.getAsTransform(transformKey)
+
+ link, linkParams = s.GetHyperlink()
)
if transform != nil {
@@ -294,62 +330,68 @@ func (s Style) Render(strs ...string) string {
return s.maybeConvertTabs(str)
}
- // Enable support for ANSI on the legacy Windows cmd.exe console. This is a
- // no-op on non-Windows systems and on Windows runs only once.
- enableLegacyWindowsANSI()
-
if bold {
te = te.Bold()
}
if italic {
- te = te.Italic()
+ te = te.Italic(true)
}
if underline {
- te = te.Underline()
+ te = te.Underline(true)
}
if reverse {
- teWhitespace = teWhitespace.Reverse()
- te = te.Reverse()
+ teWhitespace = teWhitespace.Reverse(true)
+ te = te.Reverse(true)
}
if blink {
- te = te.Blink()
+ te = te.Blink(true)
}
if faint {
te = te.Faint()
}
if fg != noColor {
- te = te.Foreground(fg.color(s.r))
+ te = te.ForegroundColor(fg)
if styleWhitespace {
- teWhitespace = teWhitespace.Foreground(fg.color(s.r))
+ teWhitespace = teWhitespace.ForegroundColor(fg)
}
if useSpaceStyler {
- teSpace = teSpace.Foreground(fg.color(s.r))
+ teSpace = teSpace.ForegroundColor(fg)
}
}
if bg != noColor {
- te = te.Background(bg.color(s.r))
+ te = te.BackgroundColor(bg)
+ if colorWhitespace {
+ teWhitespace = teWhitespace.BackgroundColor(bg)
+ }
+ if useSpaceStyler {
+ teSpace = teSpace.BackgroundColor(bg)
+ }
+ }
+
+ if ul != noColor {
+ te = te.UnderlineColor(ul)
if colorWhitespace {
- teWhitespace = teWhitespace.Background(bg.color(s.r))
+ teWhitespace = teWhitespace.UnderlineColor(ul)
}
if useSpaceStyler {
- teSpace = teSpace.Background(bg.color(s.r))
+ teSpace = teSpace.UnderlineColor(ul)
}
}
if underline {
- te = te.Underline()
+ te = te.UnderlineStyle(s.ul)
}
if strikethrough {
- te = te.CrossOut()
+ te = te.Strikethrough(true)
}
if underlineSpaces {
- teSpace = teSpace.Underline()
+ teSpace = teSpace.Underline(true)
}
if strikethroughSpaces {
- teSpace = teSpace.CrossOut()
+ teSpace = teSpace.Strikethrough(true)
}
// Potentially convert tabs to spaces
@@ -362,21 +404,30 @@ func (s Style) Render(strs ...string) string {
str = strings.ReplaceAll(str, "\n", "")
}
+ // Include borders in block size.
+ width -= horizontalBorderSize
+ height -= verticalBorderSize
+
// Word wrap
if !inline && width > 0 {
wrapAt := width - leftPadding - rightPadding
- str = cellbuf.Wrap(str, wrapAt, "")
+ str = Wrap(str, wrapAt, "")
}
// Render core text
{
var b strings.Builder
- l := strings.Split(str, "\n")
- for i := range l {
+ isFirst := true
+ for line := range strings.SplitSeq(str, "\n") {
+ if isFirst {
+ isFirst = false
+ } else {
+ b.WriteRune('\n')
+ }
if useSpaceStyler {
// Look for spaces and apply a different styler
- for _, r := range l[i] {
+ for _, r := range line {
if unicode.IsSpace(r) {
b.WriteString(teSpace.Styled(string(r)))
continue
@@ -384,32 +435,37 @@ func (s Style) Render(strs ...string) string {
b.WriteString(te.Styled(string(r)))
}
} else {
- b.WriteString(te.Styled(l[i]))
- }
- if i != len(l)-1 {
- b.WriteRune('\n')
+ b.WriteString(te.Styled(line))
}
}
str = b.String()
+
+ if len(link) > 0 {
+ str = ansi.SetHyperlink(link, linkParams) + str + ansi.ResetHyperlink()
+ }
}
// Padding
if !inline { //nolint:nestif
+ padChar := s.paddingChar
+ if padChar == 0 {
+ padChar = ' '
+ }
if leftPadding > 0 {
- var st *termenv.Style
+ var st *ansi.Style
if colorWhitespace || styleWhitespace {
st = &teWhitespace
}
- str = padLeft(str, leftPadding, st)
+ str = padLeft(str, leftPadding, st, padChar)
}
if rightPadding > 0 {
- var st *termenv.Style
+ var st *ansi.Style
if colorWhitespace || styleWhitespace {
st = &teWhitespace
}
- str = padRight(str, rightPadding, st)
+ str = padRight(str, rightPadding, st, padChar)
}
if topPadding > 0 {
@@ -433,7 +489,7 @@ func (s Style) Render(strs ...string) string {
numLines := strings.Count(str, "\n")
if numLines != 0 || width != 0 {
- var st *termenv.Style
+ var st *ansi.Style
if colorWhitespace || styleWhitespace {
st = &teWhitespace
}
@@ -491,17 +547,21 @@ func (s Style) applyMargins(str string, inline bool) string {
bottomMargin = s.getAsInt(marginBottomKey)
leftMargin = s.getAsInt(marginLeftKey)
- styler termenv.Style
+ style ansi.Style
)
bgc := s.getAsColor(marginBackgroundKey)
if bgc != noColor {
- styler = styler.Background(bgc.color(s.r))
+ style = style.BackgroundColor(bgc)
}
// Add left and right margin
- str = padLeft(str, leftMargin, &styler)
- str = padRight(str, rightMargin, &styler)
+ marginChar := s.marginChar
+ if marginChar == 0 {
+ marginChar = ' '
+ }
+ str = padLeft(str, leftMargin, &style, marginChar)
+ str = padRight(str, rightMargin, &style, marginChar)
// Top/bottom margin
if !inline {
@@ -509,10 +569,10 @@ func (s Style) applyMargins(str string, inline bool) string {
spaces := strings.Repeat(" ", width)
if topMargin > 0 {
- str = styler.Styled(strings.Repeat(spaces+"\n", topMargin)) + str
+ str = style.Styled(strings.Repeat(spaces+"\n", topMargin)) + str
}
if bottomMargin > 0 {
- str += styler.Styled(strings.Repeat("\n"+spaces, bottomMargin))
+ str += style.Styled(strings.Repeat("\n"+spaces, bottomMargin))
}
}
@@ -520,65 +580,54 @@ func (s Style) applyMargins(str string, inline bool) string {
}
// Apply left padding.
-func padLeft(str string, n int, style *termenv.Style) string {
- return pad(str, -n, style)
+func padLeft(str string, n int, style *ansi.Style, r rune) string {
+ return pad(str, -n, style, r)
}
// Apply right padding.
-func padRight(str string, n int, style *termenv.Style) string {
- return pad(str, n, style)
+func padRight(str string, n int, style *ansi.Style, r rune) string {
+ return pad(str, n, style, r)
}
// pad adds padding to either the left or right side of a string.
// Positive values add to the right side while negative values
// add to the left side.
-func pad(str string, n int, style *termenv.Style) string {
+// r is the rune to use for padding. We use " " for margins and
+// "\u00A0" for padding so that the padding is preserved when the
+// string is copied and pasted.
+func pad(str string, n int, style *ansi.Style, r rune) string {
if n == 0 {
return str
}
- sp := strings.Repeat(" ", abs(n))
+ sp := strings.Repeat(string(r), abs(n))
if style != nil {
sp = style.Styled(sp)
}
b := strings.Builder{}
- l := strings.Split(str, "\n")
-
- for i := range l {
+ isFirst := true
+ for line := range strings.SplitSeq(str, "\n") {
+ if isFirst {
+ isFirst = false
+ } else {
+ b.WriteRune('\n')
+ }
switch {
// pad right
case n > 0:
- b.WriteString(l[i])
+ b.WriteString(line)
b.WriteString(sp)
// pad left
default:
b.WriteString(sp)
- b.WriteString(l[i])
- }
-
- if i != len(l)-1 {
- b.WriteRune('\n')
+ b.WriteString(line)
}
}
return b.String()
}
-func max(a, b int) int { //nolint:unparam,predeclared
- if a > b {
- return a
- }
- return b
-}
-
-func min(a, b int) int { //nolint:predeclared
- if a < b {
- return a
- }
- return b
-}
-
func abs(a int) int {
if a < 0 {
return -a
diff --git a/tools/vendor/charm.land/lipgloss/v2/terminal.go b/tools/vendor/charm.land/lipgloss/v2/terminal.go
new file mode 100644
index 000000000..a336abc77
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/terminal.go
@@ -0,0 +1,124 @@
+package lipgloss
+
+import (
+ "fmt"
+ "image/color"
+ "io"
+ "strings"
+ "time"
+
+ uv "github.com/charmbracelet/ultraviolet"
+ "github.com/charmbracelet/x/ansi"
+)
+
+// queryBackgroundColor queries the terminal for the background color.
+// If the terminal does not support querying the background color, nil is
+// returned.
+//
+// Note: you will need to set the input to raw mode before calling this
+// function.
+//
+// state, _ := term.MakeRaw(in.Fd())
+// defer term.Restore(in.Fd(), state)
+//
+// copied from x/term@v0.1.3.
+func queryBackgroundColor(in io.Reader, out io.Writer) (c color.Color, err error) {
+ err = queryTerminal(in, out, defaultQueryTimeout,
+ func(seq string, pa *ansi.Parser) bool {
+ switch {
+ case ansi.HasOscPrefix(seq):
+ switch pa.Command() {
+ case 11: // OSC 11
+ parts := strings.Split(string(pa.Data()), ";")
+ if len(parts) != 2 {
+ break // invalid, but we still need to parse the next sequence
+ }
+ c = ansi.XParseColor(parts[1])
+ }
+ case ansi.HasCsiPrefix(seq):
+ switch pa.Command() {
+ case ansi.Command('?', 0, 'c'): // DA1
+ return false
+ }
+ }
+ return true
+ }, ansi.RequestBackgroundColor+ansi.RequestPrimaryDeviceAttributes)
+ return
+}
+
+const defaultQueryTimeout = time.Second * 2
+
+// queryTerminalFilter is a function that filters input events using a type
+// switch. If false is returned, the QueryTerminal function will stop reading
+// input.
+type queryTerminalFilter func(seq string, pa *ansi.Parser) bool
+
+// queryTerminal queries the terminal for support of various features and
+// returns a list of response events.
+// Most of the time, you will need to set stdin to raw mode before calling this
+// function.
+// Note: This function will block until the terminal responds or the timeout
+// is reached.
+// copied from x/term@v0.1.3.
+func queryTerminal(
+ in io.Reader,
+ out io.Writer,
+ timeout time.Duration,
+ filter queryTerminalFilter,
+ query string,
+) error {
+ // We use [uv.NewCancelReader] because it uses a different Windows
+ // implementation than the on in the [cancelreader] library, which uses
+ // the Cancel IO API to cancel reads instead of using Overlapped IO.
+ rd, err := uv.NewCancelReader(in)
+ if err != nil {
+ return fmt.Errorf("could not create cancel reader: %w", err)
+ }
+
+ defer rd.Close() //nolint: errcheck
+
+ done := make(chan struct{}, 1)
+ defer close(done)
+ go func() {
+ select {
+ case <-done:
+ case <-time.After(timeout):
+ rd.Cancel()
+ }
+ }()
+
+ if _, err := io.WriteString(out, query); err != nil {
+ return fmt.Errorf("could not write query: %w", err)
+ }
+
+ pa := ansi.GetParser()
+ defer ansi.PutParser(pa)
+
+ var acc []byte // Accumulate partial responses before filtering
+ var buf [256]byte // 256 bytes should be enough for most responses
+ var state byte
+ for {
+ n, err := rd.Read(buf[:])
+ if err != nil {
+ return fmt.Errorf("could not read from input: %w", err)
+ }
+
+ p := buf[:]
+ for n > 0 {
+ seq, _, read, newState := ansi.DecodeSequence(p[:n], state, pa)
+ acc = append(acc, seq...)
+
+ if newState == ansi.NormalState {
+ if !filter(string(acc), pa) {
+ return nil
+ }
+
+ acc = acc[:0]
+ }
+
+ state = newState
+ n -= read
+ p = p[read:]
+ }
+ }
+}
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/unset.go b/tools/vendor/charm.land/lipgloss/v2/unset.go
similarity index 91%
rename from tools/vendor/github.com/charmbracelet/lipgloss/unset.go
rename to tools/vendor/charm.land/lipgloss/v2/unset.go
index 1086e7226..b81ee882a 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/unset.go
+++ b/tools/vendor/charm.land/lipgloss/v2/unset.go
@@ -19,8 +19,7 @@ func (s Style) UnsetItalic() Style {
// UnsetUnderline removes the underline style rule, if set.
func (s Style) UnsetUnderline() Style {
- s.unset(underlineKey)
- return s
+ return s.Underline(false)
}
// UnsetStrikethrough removes the strikethrough style rule, if set.
@@ -96,6 +95,13 @@ func (s Style) UnsetPadding() Style {
s.unset(paddingRightKey)
s.unset(paddingTopKey)
s.unset(paddingBottomKey)
+ s.unset(paddingCharKey)
+ return s
+}
+
+// UnsetPaddingChar removes the padding character style rule, if set.
+func (s Style) UnsetPaddingChar() Style {
+ s.unset(paddingCharKey)
return s
}
@@ -237,6 +243,20 @@ func (s Style) UnsetBorderLeftForeground() Style {
return s
}
+// UnsetBorderForegroundBlend removes the border blend foreground color rules,
+// if set.
+func (s Style) UnsetBorderForegroundBlend() Style {
+ s.unset(borderForegroundBlendKey)
+ return s
+}
+
+// UnsetBorderForegroundBlendOffset removes the border blend offset style rule,
+// if set.
+func (s Style) UnsetBorderForegroundBlendOffset() Style {
+ s.unset(borderForegroundBlendOffsetKey)
+ return s
+}
+
// UnsetBorderBackground removes all border background color styles, if
// set.
func (s Style) UnsetBorderBackground() Style {
@@ -324,6 +344,14 @@ func (s Style) UnsetTransform() Style {
return s
}
+// UnsetHyperlink removes the value set by Hyperlink.
+func (s Style) UnsetHyperlink() Style {
+ s.unset(linkKey)
+ s.unset(linkParamsKey)
+ s.link, s.linkParams = "", "" // save memory
+ return s
+}
+
// UnsetString sets the underlying string value to the empty string.
func (s Style) UnsetString() Style {
s.value = ""
diff --git a/tools/vendor/github.com/charmbracelet/lipgloss/whitespace.go b/tools/vendor/charm.land/lipgloss/v2/whitespace.go
similarity index 55%
rename from tools/vendor/github.com/charmbracelet/lipgloss/whitespace.go
rename to tools/vendor/charm.land/lipgloss/v2/whitespace.go
index 040dc98e6..e353a076b 100644
--- a/tools/vendor/github.com/charmbracelet/lipgloss/whitespace.go
+++ b/tools/vendor/charm.land/lipgloss/v2/whitespace.go
@@ -4,24 +4,17 @@ import (
"strings"
"github.com/charmbracelet/x/ansi"
- "github.com/muesli/termenv"
)
// whitespace is a whitespace renderer.
type whitespace struct {
- re *Renderer
- style termenv.Style
chars string
+ style Style
}
-// newWhitespace creates a new whitespace renderer. The order of the options
-// matters, if you're using WithWhitespaceRenderer, make sure it comes first as
-// other options might depend on it.
-func newWhitespace(r *Renderer, opts ...WhitespaceOption) *whitespace {
- w := &whitespace{
- re: r,
- style: r.ColorProfile().String(),
- }
+// newWhitespace creates a new whitespace renderer.
+func newWhitespace(opts ...WhitespaceOption) *whitespace {
+ w := &whitespace{}
for _, opt := range opts {
opt(w)
}
@@ -41,11 +34,18 @@ func (w whitespace) render(width int) string {
// Cycle through runes and print them into the whitespace.
for i := 0; i < width; {
b.WriteRune(r[j])
+ // Measure the width of the rune we just wrote, ensuring we always
+ // make progress to avoid infinite loops with zero-width characters
+ // like tabs.
+ runeWidth := ansi.StringWidth(string(r[j]))
+ if runeWidth < 1 {
+ runeWidth = 1
+ }
+ i += runeWidth
j++
if j >= len(r) {
j = 0
}
- i += ansi.StringWidth(string(r[j]))
}
// Fill any extra gaps white spaces. This might be necessary if any runes
@@ -55,23 +55,16 @@ func (w whitespace) render(width int) string {
b.WriteString(strings.Repeat(" ", short))
}
- return w.style.Styled(b.String())
+ return w.style.Render(b.String())
}
// WhitespaceOption sets a styling rule for rendering whitespace.
type WhitespaceOption func(*whitespace)
-// WithWhitespaceForeground sets the color of the characters in the whitespace.
-func WithWhitespaceForeground(c TerminalColor) WhitespaceOption {
- return func(w *whitespace) {
- w.style = w.style.Foreground(c.color(w.re))
- }
-}
-
-// WithWhitespaceBackground sets the background color of the whitespace.
-func WithWhitespaceBackground(c TerminalColor) WhitespaceOption {
+// WithWhitespaceStyle sets the style for the whitespace.
+func WithWhitespaceStyle(s Style) WhitespaceOption {
return func(w *whitespace) {
- w.style = w.style.Background(c.color(w.re))
+ w.style = s
}
}
diff --git a/tools/vendor/charm.land/lipgloss/v2/wrap.go b/tools/vendor/charm.land/lipgloss/v2/wrap.go
new file mode 100644
index 000000000..ca0a1e239
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/wrap.go
@@ -0,0 +1,107 @@
+package lipgloss
+
+import (
+ "bytes"
+ "io"
+
+ uv "github.com/charmbracelet/ultraviolet"
+ "github.com/charmbracelet/x/ansi"
+)
+
+// Wrap wraps the given string to the given width, preserving ANSI styles and links.
+func Wrap(s string, width int, breakpoints string) string {
+ var buf bytes.Buffer
+ s = ansi.Wrap(s, width, breakpoints)
+ w := NewWrapWriter(&buf)
+ defer w.Close() //nolint:errcheck
+ _, _ = io.WriteString(w, s)
+ return buf.String()
+}
+
+// WrapWriter is a writer that writes to a buffer and keeps track of the
+// current pen style and link state for the purpose of wrapping with newlines.
+//
+// When it encounters a newline, it resets the style and link, writes the
+// newline, and then reapplies the style and link to the next line.
+type WrapWriter struct {
+ w io.Writer
+ p *ansi.Parser
+ style uv.Style
+ link uv.Link
+}
+
+// NewWrapWriter returns a new [WrapWriter].
+func NewWrapWriter(w io.Writer) *WrapWriter {
+ pw := &WrapWriter{w: w}
+ pw.p = ansi.GetParser()
+ handleCsi := func(cmd ansi.Cmd, params ansi.Params) {
+ if cmd == 'm' {
+ uv.ReadStyle(params, &pw.style)
+ }
+ }
+ handleOsc := func(cmd int, data []byte) {
+ if cmd == 8 {
+ uv.ReadLink(data, &pw.link)
+ }
+ }
+ pw.p.SetHandler(ansi.Handler{
+ HandleCsi: handleCsi,
+ HandleOsc: handleOsc,
+ })
+ return pw
+}
+
+// Style returns the current pen style.
+func (w *WrapWriter) Style() uv.Style {
+ return w.style
+}
+
+// Link returns the current pen link.
+func (w *WrapWriter) Link() uv.Link {
+ return w.link
+}
+
+// Write writes to the buffer.
+func (w *WrapWriter) Write(p []byte) (int, error) {
+ for i := range p {
+ b := p[i]
+ w.p.Advance(b)
+ if b == '\n' {
+ if !w.style.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetStyle))
+ }
+ if !w.link.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetHyperlink()))
+ }
+ }
+
+ _, _ = w.w.Write([]byte{b})
+ if b == '\n' {
+ if !w.link.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.SetHyperlink(w.link.URL, w.link.Params)))
+ }
+ if !w.style.IsZero() {
+ _, _ = w.w.Write([]byte(w.style.String()))
+ }
+ }
+ }
+
+ return len(p), nil
+}
+
+// Close closes the writer, resets the style and link if necessary, and releases
+// its parser. Calling it is performance critical, but forgetting it does not
+// cause safety issues or leaks.
+func (w *WrapWriter) Close() error {
+ if !w.style.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetStyle))
+ }
+ if !w.link.IsZero() {
+ _, _ = w.w.Write([]byte(ansi.ResetHyperlink()))
+ }
+ if w.p != nil {
+ ansi.PutParser(w.p)
+ w.p = nil
+ }
+ return nil
+}
diff --git a/tools/vendor/charm.land/lipgloss/v2/writer.go b/tools/vendor/charm.land/lipgloss/v2/writer.go
new file mode 100644
index 000000000..78b48b8d3
--- /dev/null
+++ b/tools/vendor/charm.land/lipgloss/v2/writer.go
@@ -0,0 +1,160 @@
+package lipgloss
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "os"
+
+ "github.com/charmbracelet/colorprofile"
+)
+
+// Writer is the default writer that prints to stdout, automatically
+// downsampling colors when necessary.
+var Writer = colorprofile.NewWriter(os.Stdout, os.Environ())
+
+// Println to stdout, automatically downsampling colors when necessary, ending
+// with a trailing newline.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("breakfast")
+//
+// Println("Time for a", str, "sandwich!")
+func Println(v ...any) (int, error) {
+ return fmt.Fprintln(Writer, v...) //nolint:wrapcheck
+}
+
+// Printf prints formatted text to stdout, automatically downsampling colors
+// when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("knuckle")
+//
+// Printf("Time for a %s sandwich!\n", str)
+func Printf(format string, v ...any) (int, error) {
+ return fmt.Fprintf(Writer, format, v...) //nolint:wrapcheck
+}
+
+// Print to stdout, automatically downsampling colors when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("Who wants marmalade?\n")
+//
+// Print(str)
+func Print(v ...any) (int, error) {
+ return fmt.Fprint(Writer, v...) //nolint:wrapcheck
+}
+
+// Fprint pritnts to the given writer, automatically downsampling colors when
+// necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("guzzle")
+//
+// Fprint(os.Stderr, "I %s horchata pretty much all the time.\n", str)
+func Fprint(w io.Writer, v ...any) (int, error) {
+ return fmt.Fprint(colorprofile.NewWriter(w, os.Environ()), v...) //nolint:wrapcheck
+}
+
+// Fprintln prints to the given writer, automatically downsampling colors when
+// necessary, and ending with a trailing newline.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("Sandwich time!")
+//
+// Fprintln(os.Stderr, str)
+func Fprintln(w io.Writer, v ...any) (int, error) {
+ return fmt.Fprintln(colorprofile.NewWriter(w, os.Environ()), v...) //nolint:wrapcheck
+}
+
+// Fprintf prints text to a writer, against the given format, automatically
+// downsampling colors when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("artichokes")
+//
+// Fprintf(os.Stderr, "I really love %s!\n", food)
+func Fprintf(w io.Writer, format string, v ...any) (int, error) {
+ return fmt.Fprintf(colorprofile.NewWriter(w, os.Environ()), format, v...) //nolint:wrapcheck
+}
+
+// Sprint returns a string for stdout, automatically downsampling colors when
+// necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Faint(true).
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("I love to eat")
+//
+// str = Sprint(str)
+func Sprint(v ...any) string {
+ var buf bytes.Buffer
+ w := colorprofile.Writer{
+ Forward: &buf,
+ Profile: Writer.Profile,
+ }
+ fmt.Fprint(&w, v...) //nolint:errcheck
+ return buf.String()
+}
+
+// Sprintln returns a string for stdout, automatically downsampling colors when
+// necessary, and ending with a trailing newline.
+//
+// Example:
+//
+// str := NewStyle().
+// Bold(true).
+// Foreground(lipgloss.Color("#6a00ff")).
+// Render("Yummy!")
+//
+// str = Sprintln(str)
+func Sprintln(v ...any) string {
+ var buf bytes.Buffer
+ w := colorprofile.Writer{
+ Forward: &buf,
+ Profile: Writer.Profile,
+ }
+ fmt.Fprintln(&w, v...) //nolint:errcheck
+ return buf.String()
+}
+
+// Sprintf returns a formatted string for stdout, automatically downsampling
+// colors when necessary.
+//
+// Example:
+//
+// str := NewStyle().
+// Bold(true).
+// Foreground(lipgloss.Color("#fccaee")).
+// Render("Cantaloupe")
+//
+// str = Sprintf("I really love %s!", str)
+func Sprintf(format string, v ...any) string {
+ var buf bytes.Buffer
+ w := colorprofile.Writer{
+ Forward: &buf,
+ Profile: Writer.Profile,
+ }
+ fmt.Fprintf(&w, format, v...) //nolint:errcheck
+ return buf.String()
+}
diff --git a/tools/vendor/github.com/ClickHouse/clickhouse-go-linter/LICENSE b/tools/vendor/github.com/ClickHouse/clickhouse-go-linter/LICENSE
new file mode 100644
index 000000000..a7e77cb28
--- /dev/null
+++ b/tools/vendor/github.com/ClickHouse/clickhouse-go-linter/LICENSE
@@ -0,0 +1,176 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
\ No newline at end of file
diff --git a/tools/vendor/github.com/ClickHouse/clickhouse-go-linter/internal/util/util.go b/tools/vendor/github.com/ClickHouse/clickhouse-go-linter/internal/util/util.go
new file mode 100644
index 000000000..68d130989
--- /dev/null
+++ b/tools/vendor/github.com/ClickHouse/clickhouse-go-linter/internal/util/util.go
@@ -0,0 +1,33 @@
+package util
+
+import (
+ "go/ast"
+ "go/types"
+
+ "golang.org/x/tools/go/analysis"
+)
+
+// IsChObj returns true if the input ast.Expr is of type clickhouse go driver