diff --git a/go.mod b/go.mod index ba965e6a889..de88035f70d 100644 --- a/go.mod +++ b/go.mod @@ -15,7 +15,7 @@ require ( github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 github.com/hashicorp/golang-lru v1.0.2 - github.com/jenkins-x/go-scm v1.14.37 + github.com/jenkins-x/go-scm v1.14.56 github.com/mitchellh/go-homedir v1.1.0 github.com/opencontainers/image-spec v1.1.0 // indirect github.com/pkg/errors v0.9.1 @@ -77,6 +77,7 @@ require ( cloud.google.com/go/kms v1.20.4 // indirect cloud.google.com/go/longrunning v0.6.2 // indirect dario.cat/mergo v1.0.0 // indirect + fortio.org/safecast v1.0.0 // indirect github.com/42wim/httpsig v1.2.1 // indirect github.com/Azure/azure-sdk-for-go/sdk/azcore v1.16.0 // indirect github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.8.0 // indirect @@ -176,7 +177,7 @@ require ( github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/blendle/zapdriver v1.3.1 // indirect - github.com/bluekeyes/go-gitdiff v0.7.1 // indirect + github.com/bluekeyes/go-gitdiff v0.8.0 // indirect github.com/census-instrumentation/opencensus-proto v0.4.1 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/chrismellard/docker-credential-acr-env v0.0.0-20230304212654-82a0ddb27589 // indirect diff --git a/go.sum b/go.sum index 4ab962dc261..656835c5c1d 100644 --- a/go.sum +++ b/go.sum @@ -63,6 +63,8 @@ contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9 dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +fortio.org/safecast v1.0.0 h1:dr3131WPX8iS1pTf76+39WeXbTrerDYLvi9s7Oi3wiY= +fortio.org/safecast v1.0.0/go.mod h1:xZmcPk3vi4kuUFf+tq4SvnlVdwViqf6ZSZl91Jr9Jdg= github.com/42wim/httpsig v1.2.1 h1:oLBxptMe9U4ZmSGtkosT8Dlfg31P3VQnAGq6psXv82Y= github.com/42wim/httpsig v1.2.1/go.mod h1:P/UYo7ytNBFwc+dg35IubuAUIs8zj5zzFIgUCEl55WY= github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= @@ -233,8 +235,8 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= -github.com/bluekeyes/go-gitdiff v0.7.1 h1:graP4ElLRshr8ecu0UtqfNTCHrtSyZd3DABQm/DWesQ= -github.com/bluekeyes/go-gitdiff v0.7.1/go.mod h1:QpfYYO1E0fTVHVZAZKiRjtSGY9823iCdvGXBcEzHGbM= +github.com/bluekeyes/go-gitdiff v0.8.0 h1:Nn1wfw3/XeKoc3lWk+2bEXGUHIx36kj80FM1gVcBk+o= +github.com/bluekeyes/go-gitdiff v0.8.0/go.mod h1:WWAk1Mc6EgWarCrPFO+xeYlujPu98VuLW3Tu+B/85AE= github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= @@ -737,8 +739,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jellydator/ttlcache/v3 v3.3.0 h1:BdoC9cE81qXfrxeb9eoJi9dWrdhSuwXMAnHTbnBm4Wc= github.com/jellydator/ttlcache/v3 v3.3.0/go.mod h1:bj2/e0l4jRnQdrnSTaGTsh4GSXvMjQcy41i7th0GVGw= -github.com/jenkins-x/go-scm v1.14.37 h1:Tq59JXyg5p4iuvIKf6+EA+Yzgxgpn/yG/yfM1mL8DDg= -github.com/jenkins-x/go-scm v1.14.37/go.mod h1:MRLj/i0mhpMtqwwZV+x78SkEB8mx9rv3ebdRg9WunS8= +github.com/jenkins-x/go-scm v1.14.56 h1:+kKwbTv+6ymaxx4bBCEMLvkrjLmFkWX39qxYe4DDHPI= +github.com/jenkins-x/go-scm v1.14.56/go.mod h1:1RPxLZndnvu31XhFZ+RTvXiHmMX70HkQ17bRupTQxGs= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= diff --git a/vendor/fortio.org/safecast/.gitignore b/vendor/fortio.org/safecast/.gitignore new file mode 100644 index 00000000000..6f72f892618 --- /dev/null +++ b/vendor/fortio.org/safecast/.gitignore @@ -0,0 +1,25 @@ +# If you prefer the allow list template instead of the deny list, see community template: +# https://github.com/github/gitignore/blob/main/community/Golang/Go.AllowList.gitignore +# +# Binaries for programs and plugins +*.exe +*.exe~ +*.dll +*.so +*.dylib + +# Test binary, built with `go test -c` +*.test + +# Output of the go coverage tool, specifically when used with LiteIDE +*.out + +# Dependency directories (remove the comment below to include it) +# vendor/ + +# Go workspace file +go.work +go.work.sum + +# env file +.env diff --git a/vendor/fortio.org/safecast/LICENSE b/vendor/fortio.org/safecast/LICENSE new file mode 100644 index 00000000000..261eeb9e9f8 --- /dev/null +++ b/vendor/fortio.org/safecast/LICENSE @@ -0,0 +1,201 @@ + 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 + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/vendor/fortio.org/safecast/README.md b/vendor/fortio.org/safecast/README.md new file mode 100644 index 00000000000..2ae765fcdf5 --- /dev/null +++ b/vendor/fortio.org/safecast/README.md @@ -0,0 +1,18 @@ +# safecast + +[![Go Report Card](https://goreportcard.com/badge/fortio.org/safecast)](https://goreportcard.com/report/fortio.org/safecast) +[![GoDoc](https://godoc.org/fortio.org/safecast?status.svg)](https://pkg.go.dev/fortio.org/safecast) +[![codecov](https://codecov.io/gh/fortio/safecast/branch/main/graph/badge.svg)](https://codecov.io/gh/fortio/safecast) +[![Maintainability](https://api.codeclimate.com/v1/badges/bf83c496d49b169cd744/maintainability)](https://codeclimate.com/github/fortio/safecast/maintainability) +[![CI Checks](https://github.com/fortio/safecast/actions/workflows/include.yml/badge.svg)](https://github.com/fortio/safecast/actions/workflows/include.yml) + +Avoid accidental overflow of numbers during go type conversions (e.g instead of `shorter := bigger.(int8)` type conversions use `shorter := safecast.MustConvert[int8](bigger)`. + +Safecast allows you to safely convert between numeric types in Go and return errors (or panic when using the `Must*` variants) when the cast would result in a loss of precision, range or sign. + +See https://pkg.go.dev/fortio.org/safecast for docs and example. +This is usable from any go with generics (1.18 or later) though our CI uses the latest go. + +`safecast` is about avoiding [gosec G115](https://github.com/securego/gosec#available-rules) and [CWE-190: Integer Overflow or Wraparound](https://cwe.mitre.org/data/definitions/190.html) class of overflow and loss of precision bugs, extended to float64/float32 issues. + +Credit for the idea (and a finding a bug in the first implementation) goes to [@ccoVeille](https://github.com/ccoVeille), Please see https://github.com/ccoVeille/go-safecast for an different style API and implementation to pick whichever fits your style best. diff --git a/vendor/fortio.org/safecast/SECURITY.md b/vendor/fortio.org/safecast/SECURITY.md new file mode 100644 index 00000000000..c9908aaed00 --- /dev/null +++ b/vendor/fortio.org/safecast/SECURITY.md @@ -0,0 +1,9 @@ +# Security Policy + +## Supported Versions + +Latest tag is the only supported version. + +## Reporting a Vulnerability + +Please report any issue or bug through https://github.com/fortio/safecast/issues/new diff --git a/vendor/fortio.org/safecast/safecast.go b/vendor/fortio.org/safecast/safecast.go new file mode 100644 index 00000000000..3d53cad3f81 --- /dev/null +++ b/vendor/fortio.org/safecast/safecast.go @@ -0,0 +1,98 @@ +// Package safecast allows you to safely cast between numeric types in Go and return errors (or panic when using the +// Must* variants) when the cast would result in a loss of precision, range or sign. +package safecast + +// Implementation: me (@ldemailly), idea: @ccoVeille - https://github.com/ccoVeille/go-safecast +// Started https://github.com/ldemailly/go-scratch/commits/main/safecast/safecast.go +// then moved here to fortio.org/safecast + +import ( + "errors" + "fmt" + "math" +) + +type Integer interface { + // Same as golang.org/x/contraints.Integer but without importing the whole thing for 1 line. + ~int | ~uint | ~int8 | ~uint8 | ~int16 | ~uint16 | ~int32 | ~uint32 | ~int64 | ~uint64 | ~uintptr +} + +type Float interface { + ~float32 | ~float64 +} + +type Number interface { + Integer | Float +} + +var ErrOutOfRange = errors.New("out of range") + +const all64bitsOne = ^uint64(0) // same as uint64(math.MaxUint64) + +// Convert converts a number from one type to another, +// returning an error if the conversion would result in a loss of precision, +// range or sign (overflow). In other words if the converted number is not +// equal to the original number. +// Do not use for identity (same type in and out) but in particular this +// will error for Convert[uint64](uint64(math.MaxUint64)) because it needs to +// when converting to any float. +func Convert[NumOut Number, NumIn Number](orig NumIn) (converted NumOut, err error) { + origPositive := orig > 0 + // all bits set on uint64 is the only special case not detected by roundtrip (afaik). + if origPositive && (uint64(orig) == all64bitsOne) { + err = ErrOutOfRange + return + } + converted = NumOut(orig) + if origPositive != (converted > 0) { + err = ErrOutOfRange + return + } + if NumIn(converted) != orig { + err = ErrOutOfRange + } + return +} + +// Same as Convert but panics if there is an error. +func MustConvert[NumOut Number, NumIn Number](orig NumIn) NumOut { + converted, err := Convert[NumOut, NumIn](orig) + if err != nil { + doPanic(err, orig, converted) + } + return converted +} + +// Converts a float to an integer by truncating the fractional part. +// Returns an error if the conversion would result in a loss of precision. +func Truncate[NumOut Number, NumIn Float](orig NumIn) (converted NumOut, err error) { + return Convert[NumOut](math.Trunc(float64(orig))) +} + +// Converts a float to an integer by rounding to the nearest integer. +// Returns an error if the conversion would result in a loss of precision. +func Round[NumOut Number, NumIn Float](orig NumIn) (converted NumOut, err error) { + return Convert[NumOut](math.Round(float64(orig))) +} + +// Same as Truncate but panics if there is an error. +func MustTruncate[NumOut Number, NumIn Float](orig NumIn) NumOut { + converted, err := Truncate[NumOut, NumIn](orig) + if err != nil { + doPanic(err, orig, converted) + } + return converted +} + +// Same as Round but panics if there is an error. +func MustRound[NumOut Number, NumIn Float](orig NumIn) NumOut { + converted, err := Round[NumOut, NumIn](orig) + if err != nil { + doPanic(err, orig, converted) + } + return converted +} + +func doPanic[NumOut Number, NumIn Number](err error, orig NumIn, converted NumOut) { + panic(fmt.Sprintf("safecast: %v for %v (%T) to %T", err, orig, orig, converted)) +} diff --git a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/base85.go b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/base85.go index 385aa64481d..86db1175a5f 100644 --- a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/base85.go +++ b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/base85.go @@ -19,8 +19,8 @@ func init() { } // base85Decode decodes Base85-encoded data from src into dst. It uses the -// alphabet defined by base85.c in the Git source tree, which appears to be -// unique. src must contain at least len(dst) bytes of encoded data. +// alphabet defined by base85.c in the Git source tree. src must contain at +// least len(dst) bytes of encoded data. func base85Decode(dst, src []byte) error { var v uint32 var n, ndst int @@ -50,3 +50,42 @@ func base85Decode(dst, src []byte) error { } return nil } + +// base85Encode encodes src in Base85, writing the result to dst. It uses the +// alphabet defined by base85.c in the Git source tree. +func base85Encode(dst, src []byte) { + var di, si int + + encode := func(v uint32) { + dst[di+0] = b85Alpha[(v/(85*85*85*85))%85] + dst[di+1] = b85Alpha[(v/(85*85*85))%85] + dst[di+2] = b85Alpha[(v/(85*85))%85] + dst[di+3] = b85Alpha[(v/85)%85] + dst[di+4] = b85Alpha[v%85] + } + + n := (len(src) / 4) * 4 + for si < n { + encode(uint32(src[si+0])<<24 | uint32(src[si+1])<<16 | uint32(src[si+2])<<8 | uint32(src[si+3])) + si += 4 + di += 5 + } + + var v uint32 + switch len(src) - si { + case 3: + v |= uint32(src[si+2]) << 8 + fallthrough + case 2: + v |= uint32(src[si+1]) << 16 + fallthrough + case 1: + v |= uint32(src[si+0]) << 24 + encode(v) + } +} + +// base85Len returns the length of n bytes of Base85 encoded data. +func base85Len(n int) int { + return (n + 3) / 4 * 5 +} diff --git a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/file_header.go b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/file_header.go index 77ceb5d8bf6..7ae4bc91f98 100644 --- a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/file_header.go +++ b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/file_header.go @@ -57,7 +57,7 @@ func (p *parser) ParseNextFileHeader() (*File, string, error) { return nil, "", err } } - return nil, "", nil + return nil, preamble.String(), nil } func (p *parser) ParseGitFileHeader() (*File, error) { diff --git a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/format.go b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/format.go new file mode 100644 index 00000000000..5653f6f2a6b --- /dev/null +++ b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/format.go @@ -0,0 +1,277 @@ +package gitdiff + +import ( + "bytes" + "compress/zlib" + "fmt" + "io" + "strconv" +) + +type formatter struct { + w io.Writer + err error +} + +func newFormatter(w io.Writer) *formatter { + return &formatter{w: w} +} + +func (fm *formatter) Write(p []byte) (int, error) { + if fm.err != nil { + return len(p), nil + } + if _, err := fm.w.Write(p); err != nil { + fm.err = err + } + return len(p), nil +} + +func (fm *formatter) WriteString(s string) (int, error) { + fm.Write([]byte(s)) + return len(s), nil +} + +func (fm *formatter) WriteByte(c byte) error { + fm.Write([]byte{c}) + return nil +} + +func (fm *formatter) WriteQuotedName(s string) { + qpos := 0 + for i := 0; i < len(s); i++ { + ch := s[i] + if q, quoted := quoteByte(ch); quoted { + if qpos == 0 { + fm.WriteByte('"') + } + fm.WriteString(s[qpos:i]) + fm.Write(q) + qpos = i + 1 + } + } + fm.WriteString(s[qpos:]) + if qpos > 0 { + fm.WriteByte('"') + } +} + +var quoteEscapeTable = map[byte]byte{ + '\a': 'a', + '\b': 'b', + '\t': 't', + '\n': 'n', + '\v': 'v', + '\f': 'f', + '\r': 'r', + '"': '"', + '\\': '\\', +} + +func quoteByte(b byte) ([]byte, bool) { + if q, ok := quoteEscapeTable[b]; ok { + return []byte{'\\', q}, true + } + if b < 0x20 || b >= 0x7F { + return []byte{ + '\\', + '0' + (b>>6)&0o3, + '0' + (b>>3)&0o7, + '0' + (b>>0)&0o7, + }, true + } + return nil, false +} + +func (fm *formatter) FormatFile(f *File) { + fm.WriteString("diff --git ") + + var aName, bName string + switch { + case f.OldName == "": + aName = f.NewName + bName = f.NewName + + case f.NewName == "": + aName = f.OldName + bName = f.OldName + + default: + aName = f.OldName + bName = f.NewName + } + + fm.WriteQuotedName("a/" + aName) + fm.WriteByte(' ') + fm.WriteQuotedName("b/" + bName) + fm.WriteByte('\n') + + if f.OldMode != 0 { + if f.IsDelete { + fmt.Fprintf(fm, "deleted file mode %o\n", f.OldMode) + } else if f.NewMode != 0 { + fmt.Fprintf(fm, "old mode %o\n", f.OldMode) + } + } + + if f.NewMode != 0 { + if f.IsNew { + fmt.Fprintf(fm, "new file mode %o\n", f.NewMode) + } else if f.OldMode != 0 { + fmt.Fprintf(fm, "new mode %o\n", f.NewMode) + } + } + + if f.Score > 0 { + if f.IsCopy || f.IsRename { + fmt.Fprintf(fm, "similarity index %d%%\n", f.Score) + } else { + fmt.Fprintf(fm, "dissimilarity index %d%%\n", f.Score) + } + } + + if f.IsCopy { + if f.OldName != "" { + fm.WriteString("copy from ") + fm.WriteQuotedName(f.OldName) + fm.WriteByte('\n') + } + if f.NewName != "" { + fm.WriteString("copy to ") + fm.WriteQuotedName(f.NewName) + fm.WriteByte('\n') + } + } + + if f.IsRename { + if f.OldName != "" { + fm.WriteString("rename from ") + fm.WriteQuotedName(f.OldName) + fm.WriteByte('\n') + } + if f.NewName != "" { + fm.WriteString("rename to ") + fm.WriteQuotedName(f.NewName) + fm.WriteByte('\n') + } + } + + if f.OldOIDPrefix != "" && f.NewOIDPrefix != "" { + fmt.Fprintf(fm, "index %s..%s", f.OldOIDPrefix, f.NewOIDPrefix) + + // Mode is only included on the index line when it is not changing + if f.OldMode != 0 && ((f.NewMode == 0 && !f.IsDelete) || f.OldMode == f.NewMode) { + fmt.Fprintf(fm, " %o", f.OldMode) + } + + fm.WriteByte('\n') + } + + if f.IsBinary { + if f.BinaryFragment == nil { + fm.WriteString("Binary files fmer\n") + } else { + fm.WriteString("GIT binary patch\n") + fm.FormatBinaryFragment(f.BinaryFragment) + if f.ReverseBinaryFragment != nil { + fm.FormatBinaryFragment(f.ReverseBinaryFragment) + } + } + } + + // The "---" and "+++" lines only appear for text patches with fragments + if len(f.TextFragments) > 0 { + fm.WriteString("--- ") + if f.OldName == "" { + fm.WriteString("/dev/null") + } else { + fm.WriteQuotedName("a/" + f.OldName) + } + fm.WriteByte('\n') + + fm.WriteString("+++ ") + if f.NewName == "" { + fm.WriteString("/dev/null") + } else { + fm.WriteQuotedName("b/" + f.NewName) + } + fm.WriteByte('\n') + + for _, frag := range f.TextFragments { + fm.FormatTextFragment(frag) + } + } +} + +func (fm *formatter) FormatTextFragment(f *TextFragment) { + fm.FormatTextFragmentHeader(f) + fm.WriteByte('\n') + + for _, line := range f.Lines { + fm.WriteString(line.Op.String()) + fm.WriteString(line.Line) + if line.NoEOL() { + fm.WriteString("\n\\ No newline at end of file\n") + } + } +} + +func (fm *formatter) FormatTextFragmentHeader(f *TextFragment) { + fmt.Fprintf(fm, "@@ -%d,%d +%d,%d @@", f.OldPosition, f.OldLines, f.NewPosition, f.NewLines) + if f.Comment != "" { + fm.WriteByte(' ') + fm.WriteString(f.Comment) + } +} + +func (fm *formatter) FormatBinaryFragment(f *BinaryFragment) { + const ( + maxBytesPerLine = 52 + ) + + switch f.Method { + case BinaryPatchDelta: + fm.WriteString("delta ") + case BinaryPatchLiteral: + fm.WriteString("literal ") + } + fm.Write(strconv.AppendInt(nil, f.Size, 10)) + fm.WriteByte('\n') + + data := deflateBinaryChunk(f.Data) + n := (len(data) / maxBytesPerLine) * maxBytesPerLine + + buf := make([]byte, base85Len(maxBytesPerLine)) + for i := 0; i < n; i += maxBytesPerLine { + base85Encode(buf, data[i:i+maxBytesPerLine]) + fm.WriteByte('z') + fm.Write(buf) + fm.WriteByte('\n') + } + if remainder := len(data) - n; remainder > 0 { + buf = buf[0:base85Len(remainder)] + + sizeChar := byte(remainder) + if remainder <= 26 { + sizeChar = 'A' + sizeChar - 1 + } else { + sizeChar = 'a' + sizeChar - 27 + } + + base85Encode(buf, data[n:]) + fm.WriteByte(sizeChar) + fm.Write(buf) + fm.WriteByte('\n') + } + fm.WriteByte('\n') +} + +func deflateBinaryChunk(data []byte) []byte { + var b bytes.Buffer + + zw := zlib.NewWriter(&b) + _, _ = zw.Write(data) + _ = zw.Close() + + return b.Bytes() +} diff --git a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/gitdiff.go b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/gitdiff.go index 18645bd0398..536564545dc 100644 --- a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/gitdiff.go +++ b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/gitdiff.go @@ -4,6 +4,7 @@ import ( "errors" "fmt" "os" + "strings" ) // File describes changes to a single file. It can be either a text file or a @@ -38,6 +39,15 @@ type File struct { ReverseBinaryFragment *BinaryFragment } +// String returns a git diff representation of this file. The value can be +// parsed by this library to obtain the same File, but may not be the same as +// the original input. +func (f *File) String() string { + var diff strings.Builder + newFormatter(&diff).FormatFile(f) + return diff.String() +} + // TextFragment describes changed lines starting at a specific line in a text file. type TextFragment struct { Comment string @@ -57,9 +67,20 @@ type TextFragment struct { Lines []Line } -// Header returns the canonical header of this fragment. +// String returns a git diff format of this fragment. See [File.String] for +// more details on this format. +func (f *TextFragment) String() string { + var diff strings.Builder + newFormatter(&diff).FormatTextFragment(f) + return diff.String() +} + +// Header returns a git diff header of this fragment. See [File.String] for +// more details on this format. func (f *TextFragment) Header() string { - return fmt.Sprintf("@@ -%d,%d +%d,%d @@ %s", f.OldPosition, f.OldLines, f.NewPosition, f.NewLines, f.Comment) + var hdr strings.Builder + newFormatter(&hdr).FormatTextFragmentHeader(f) + return hdr.String() } // Validate checks that the fragment is self-consistent and appliable. Validate @@ -197,3 +218,13 @@ const ( // BinaryPatchLiteral indicates the data is the exact file content BinaryPatchLiteral ) + +// String returns a git diff format of this fragment. Due to differences in +// zlib implementation between Go and Git, encoded binary data in the result +// will likely differ from what Git produces for the same input. See +// [File.String] for more details on this format. +func (f *BinaryFragment) String() string { + var diff strings.Builder + newFormatter(&diff).FormatBinaryFragment(f) + return diff.String() +} diff --git a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/parser.go b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/parser.go index d44465a9ee0..e8f8430f520 100644 --- a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/parser.go +++ b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/parser.go @@ -12,6 +12,10 @@ import ( // Parse parses a patch with changes to one or more files. Any content before // the first file is returned as the second value. If an error occurs while // parsing, it returns all files parsed before the error. +// +// Parse expects to receive a single patch. If the input may contain multiple +// patches (for example, if it is an mbox file), callers should split it into +// individual patches and call Parse on each one. func Parse(r io.Reader) ([]*File, string, error) { p := newParser(r) @@ -29,6 +33,9 @@ func Parse(r io.Reader) ([]*File, string, error) { if err != nil { return files, preamble, err } + if len(files) == 0 { + preamble = pre + } if file == nil { break } @@ -46,9 +53,6 @@ func Parse(r io.Reader) ([]*File, string, error) { } } - if len(files) == 0 { - preamble = pre - } files = append(files, file) } diff --git a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/patch_header.go b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/patch_header.go index f935c6de1a0..f047059ba6e 100644 --- a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/patch_header.go +++ b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/patch_header.go @@ -68,55 +68,6 @@ func (h *PatchHeader) Message() string { return msg.String() } -// PatchIdentity identifies a person who authored or committed a patch. -type PatchIdentity struct { - Name string - Email string -} - -func (i PatchIdentity) String() string { - name := i.Name - if name == "" { - name = `""` - } - return fmt.Sprintf("%s <%s>", name, i.Email) -} - -// ParsePatchIdentity parses a patch identity string. A valid string contains a -// non-empty name followed by an email address in angle brackets. Like Git, -// ParsePatchIdentity does not require that the email address is valid or -// properly formatted, only that it is non-empty. The name must not contain a -// left angle bracket, '<', and the email address must not contain a right -// angle bracket, '>'. -func ParsePatchIdentity(s string) (PatchIdentity, error) { - var emailStart, emailEnd int - for i, c := range s { - if c == '<' && emailStart == 0 { - emailStart = i + 1 - } - if c == '>' && emailStart > 0 { - emailEnd = i - break - } - } - if emailStart > 0 && emailEnd == 0 { - return PatchIdentity{}, fmt.Errorf("invalid identity string: unclosed email section: %s", s) - } - - var name, email string - if emailStart > 0 { - name = strings.TrimSpace(s[:emailStart-1]) - } - if emailStart > 0 && emailEnd > 0 { - email = strings.TrimSpace(s[emailStart:emailEnd]) - } - if name == "" || email == "" { - return PatchIdentity{}, fmt.Errorf("invalid identity string: %s", s) - } - - return PatchIdentity{Name: name, Email: email}, nil -} - // ParsePatchDate parses a patch date string. It returns the parsed time or an // error if s has an unknown format. ParsePatchDate supports the iso, rfc, // short, raw, unix, and default formats (with local variants) used by the @@ -418,16 +369,13 @@ func parseHeaderMail(mailLine string, r io.Reader, opts patchHeaderOptions) (*Pa } } - addrs, err := msg.Header.AddressList("From") - if err != nil && !errors.Is(err, mail.ErrHeaderNotPresent) { - return nil, err - } - if len(addrs) > 0 { - addr := addrs[0] - if addr.Name == "" { - addr.Name = addr.Address + from := msg.Header.Get("From") + if from != "" { + u, err := ParsePatchIdentity(from) + if err != nil { + return nil, err } - h.Author = &PatchIdentity{Name: addr.Name, Email: addr.Address} + h.Author = &u } date := msg.Header.Get("Date") diff --git a/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/patch_identity.go b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/patch_identity.go new file mode 100644 index 00000000000..018f80c765f --- /dev/null +++ b/vendor/github.com/bluekeyes/go-gitdiff/gitdiff/patch_identity.go @@ -0,0 +1,166 @@ +package gitdiff + +import ( + "fmt" + "strings" +) + +// PatchIdentity identifies a person who authored or committed a patch. +type PatchIdentity struct { + Name string + Email string +} + +func (i PatchIdentity) String() string { + name := i.Name + if name == "" { + name = `""` + } + return fmt.Sprintf("%s <%s>", name, i.Email) +} + +// ParsePatchIdentity parses a patch identity string. A patch identity contains +// an email address and an optional name in [RFC 5322] format. This is either a +// plain email adddress or a name followed by an address in angle brackets: +// +// author@example.com +// Author Name +// +// If the input is not one of these formats, ParsePatchIdentity applies a +// heuristic to separate the name and email portions. If both the name and +// email are missing or empty, ParsePatchIdentity returns an error. It +// otherwise does not validate the result. +// +// [RFC 5322]: https://datatracker.ietf.org/doc/html/rfc5322 +func ParsePatchIdentity(s string) (PatchIdentity, error) { + s = normalizeSpace(s) + s = unquotePairs(s) + + var name, email string + if at := strings.IndexByte(s, '@'); at >= 0 { + start, end := at, at + for start >= 0 && !isRFC5332Space(s[start]) && s[start] != '<' { + start-- + } + for end < len(s) && !isRFC5332Space(s[end]) && s[end] != '>' { + end++ + } + email = s[start+1 : end] + + // Adjust the boundaries so that we drop angle brackets, but keep + // spaces when removing the email to form the name. + if start < 0 || s[start] != '<' { + start++ + } + if end >= len(s) || s[end] != '>' { + end-- + } + name = s[:start] + s[end+1:] + } else { + start, end := 0, 0 + for i := 0; i < len(s); i++ { + if s[i] == '<' && start == 0 { + start = i + 1 + } + if s[i] == '>' && start > 0 { + end = i + break + } + } + if start > 0 && end >= start { + email = strings.TrimSpace(s[start:end]) + name = s[:start-1] + } + } + + // After extracting the email, the name might contain extra whitespace + // again and may be surrounded by comment characters. The git source gives + // these examples of when this can happen: + // + // "Name " + // "email@domain (Name)" + // "Name (Comment)" + // + name = normalizeSpace(name) + if strings.HasPrefix(name, "(") && strings.HasSuffix(name, ")") { + name = name[1 : len(name)-1] + } + name = strings.TrimSpace(name) + + // If the name is empty or contains email-like characters, use the email + // instead (assuming one exists) + if name == "" || strings.ContainsAny(name, "@<>") { + name = email + } + + if name == "" && email == "" { + return PatchIdentity{}, fmt.Errorf("invalid identity string %q", s) + } + return PatchIdentity{Name: name, Email: email}, nil +} + +// unquotePairs process the RFC5322 tokens "quoted-string" and "comment" to +// remove any "quoted-pairs" (backslash-espaced characters). It also removes +// the quotes from any quoted strings, but leaves the comment delimiters. +func unquotePairs(s string) string { + quote := false + comments := 0 + escaped := false + + var out strings.Builder + for i := 0; i < len(s); i++ { + if escaped { + escaped = false + } else { + switch s[i] { + case '\\': + // quoted-pair is only allowed in quoted-string/comment + if quote || comments > 0 { + escaped = true + continue // drop '\' character + } + + case '"': + if comments == 0 { + quote = !quote + continue // drop '"' character + } + + case '(': + if !quote { + comments++ + } + case ')': + if comments > 0 { + comments-- + } + } + } + out.WriteByte(s[i]) + } + return out.String() +} + +// normalizeSpace trims leading and trailing whitespace from s and converts +// inner sequences of one or more whitespace characters to single spaces. +func normalizeSpace(s string) string { + var sb strings.Builder + for i := 0; i < len(s); i++ { + c := s[i] + if !isRFC5332Space(c) { + if sb.Len() > 0 && isRFC5332Space(s[i-1]) { + sb.WriteByte(' ') + } + sb.WriteByte(c) + } + } + return sb.String() +} + +func isRFC5332Space(c byte) bool { + switch c { + case '\t', '\n', '\r', ' ': + return true + } + return false +} diff --git a/vendor/github.com/jenkins-x/go-scm/scm/const.go b/vendor/github.com/jenkins-x/go-scm/scm/const.go index 3f1db75fa62..d2555c51c38 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/const.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/const.go @@ -141,7 +141,7 @@ func (a Action) String() (s string) { case ActionSubmitted: return "submitted" case ActionDismissed: - return "dismisssed" + return "dismissed" case ActionAssigned: return "assigned" case ActionUnassigned: @@ -205,6 +205,14 @@ func (a *Action) UnmarshalJSON(data []byte) error { *a = ActionDismissed case "edited": *a = ActionEdited + case "assigned": + *a = ActionAssigned + case "unassigned": + *a = ActionUnassigned + case "review_requested": + *a = ActionReviewRequested + case "review_request_removed": + *a = ActionReviewRequestRemoved } return nil } diff --git a/vendor/github.com/jenkins-x/go-scm/scm/content.go b/vendor/github.com/jenkins-x/go-scm/scm/content.go index c2ecff7dfde..231d7751cfd 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/content.go @@ -43,7 +43,7 @@ type ( Find(ctx context.Context, repo, path, ref string) (*Content, *Response, error) // List the files or directories at the given path - List(ctx context.Context, repo, path, ref string) ([]*FileEntry, *Response, error) + List(ctx context.Context, repo, path, ref string, opts *ListOptions) ([]*FileEntry, *Response, error) // Create creates a new repository file. Create(ctx context.Context, repo, path string, params *ContentParams) (*Response, error) diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/content.go index 0d53ae331ff..30a27491b56 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/content.go @@ -127,7 +127,7 @@ func (s *contentService) Delete(ctx context.Context, repo, path string, params * return res, err } -func (s *contentService) List(ctx context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { +func (s *contentService) List(ctx context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { // https://docs.microsoft.com/en-us/rest/api/azure/devops/git/items/list?view=azure-devops-rest-6.0 ro, err := decodeRepo(repo) if err != nil { diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/git.go index 8be89cbb44e..4e8f26070d1 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/git.go @@ -131,6 +131,10 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, source, target st return convertChangeList(changes), res, err } +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} + type gitRef struct { Name string `json:"name"` OldObjectID string `json:"oldObjectId"` diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/pr.go index 69757c29ae3..debd54631a6 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/pr.go @@ -169,6 +169,10 @@ func (s *pullService) Create(ctx context.Context, repo string, input *scm.PullRe return convertPullRequest(out), res, err } +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + type prInput struct { SourceRefName string `json:"sourceRefName"` TargetRefName string `json:"targetRefName"` diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/repo.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/repo.go index 0e96b87b3f0..2d3dfd1e898 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/repo.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/azure/repo.go @@ -10,6 +10,8 @@ import ( "net/url" "strings" + "fortio.org/safecast" + "github.com/jenkins-x/go-scm/scm" ) @@ -223,8 +225,8 @@ func convertRepositoryList(from *repositories, options *scm.ListOptions) []*scm. var to []*scm.Repository paging := options.Size > 0 - start := uint64(options.Page * options.Size) - end := start + uint64(options.Size) + start := safecast.MustConvert[uint64](options.Page * options.Size) + end := start + safecast.MustConvert[uint64](options.Size) var curr uint64 for _, v := range from.Value { diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/content.go index e011961dfbe..226b1810ee6 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/content.go @@ -26,7 +26,7 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm }, res, err } -func (s *contentService) List(ctx context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { +func (s *contentService) List(ctx context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { return nil, nil, scm.ErrNotSupported } diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/git.go index f4a8c9bf231..c55432eda8f 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/git.go @@ -132,6 +132,14 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, ref1, ref2 string return convertDiffstats(out), res, err } +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + repository, res, err := s.client.Repositories.Find(ctx, repo) + if err != nil { + return nil, res, err + } + return s.FindBranch(ctx, repo, repository.Branch) +} + type branch struct { Type string `json:"type"` Name string `json:"name"` diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/pr.go index 785c5205718..8251931981d 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/bitbucket/pr.go @@ -284,6 +284,10 @@ func (s *pullService) UnrequestReview(ctx context.Context, repo string, number i return nil, scm.ErrNotSupported } +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + type prSource struct { Commit struct { Type string `json:"type"` diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/content.go index 819524b84c4..11fe09d16df 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/content.go @@ -43,7 +43,7 @@ func (c contentService) Find(_ context.Context, repo, path, ref string) (*scm.Co }, nil, nil } -func (c contentService) List(_ context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { +func (c contentService) List(_ context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { dir, err := c.path(repo, path, ref) if err != nil { return nil, nil, err diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/git.go index 703bce30213..47e3bf4dae8 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/git.go @@ -66,3 +66,7 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, ref1, ref2 string func (s *gitService) ListTags(ctx context.Context, repo string, opts *scm.ListOptions) ([]*scm.Reference, *scm.Response, error) { panic("implement me") } + +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + return nil, nil, scm.ErrNotSupported +} diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/pr.go index fb5f25656ec..93847729916 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/fake/pr.go @@ -376,3 +376,7 @@ func (s *pullService) SetMilestone(ctx context.Context, repo string, prID, numbe func (s *pullService) ClearMilestone(ctx context.Context, repo string, prID int) (*scm.Response, error) { return nil, scm.ErrNotSupported } + +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/content.go index 56a43c45da3..709b703795f 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/content.go @@ -36,7 +36,7 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm }, toSCMResponse(resp), err } -func (s *contentService) List(ctx context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { +func (s *contentService) List(ctx context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { namespace, name := scm.Split(repo) ref = strings.TrimPrefix(ref, "refs/heads/") diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/git.go index 110952578c0..7187c0c22ce 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/git.go @@ -102,6 +102,14 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, ref1, ref2 string return nil, nil, scm.ErrNotSupported } +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + repository, res, err := s.client.Repositories.Find(ctx, repo) + if err != nil { + return nil, res, err + } + return s.FindBranch(ctx, repo, repository.Branch) +} + // // native data structures // diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/pr.go index 092e07c3b4e..6a65814dd93 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/pr.go @@ -144,6 +144,10 @@ func (s *pullService) UnrequestReview(ctx context.Context, repo string, number i return s.UnassignIssue(ctx, repo, number, logins) } +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + // // native data structure conversion // diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/review.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/review.go index e28030d9a40..8099ca097d0 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/review.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitea/review.go @@ -8,6 +8,7 @@ import ( "context" "code.gitea.io/sdk/gitea" + "fortio.org/safecast" "github.com/jenkins-x/go-scm/scm" ) @@ -114,7 +115,7 @@ func convertReviewComment(src *gitea.PullReviewComment) *scm.ReviewComment { Body: src.Body, Path: src.Path, Sha: src.CommitID, - Line: int(src.LineNum), + Line: safecast.MustConvert[int](src.LineNum), Link: src.HTMLURL, Author: *convertUser(src.Reviewer), Created: src.Created, diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/content.go index 0047a575ad0..55c9845d121 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/content.go @@ -28,7 +28,7 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm }, res, err } -func (s *contentService) List(ctx context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { +func (s *contentService) List(ctx context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { endpoint := fmt.Sprintf("repos/%s/contents/%s?ref=%s", repo, path, ref) out := []*entry{} res, err := s.client.do(ctx, "GET", endpoint, nil, &out) diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/git.go index 61cc087d42c..b3dccfaacd9 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/git.go @@ -115,6 +115,14 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, ref1, ref2 string return convertChangeList(out.Files), res, err } +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + repository, res, err := s.client.Repositories.Find(ctx, repo) + if err != nil { + return nil, res, err + } + return s.FindBranch(ctx, repo, repository.Branch) +} + type branch struct { Name string `json:"name"` Commit commit `json:"commit"` diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/issue.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/issue.go index 109d5e06141..480ecc08df1 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/issue.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/issue.go @@ -266,7 +266,7 @@ type issue struct { UpdatedAt time.Time `json:"updated_at"` // This will be non-nil if it is a pull request. - PullRequest pr `json:"pull_request,omitempty"` + PullRequest *pr `json:"pull_request,omitempty"` } type issueInput struct { @@ -349,6 +349,13 @@ func convertIssue(from *issue) *scm.Issue { Avatar: from.ClosedBy.AvatarURL, } } + var pullRequest *scm.PullRequest + if from.PullRequest != nil { + pullRequest = &scm.PullRequest{ + DiffLink: from.PullRequest.DiffURL, + Link: from.PullRequest.HTMLURL, + } + } return &scm.Issue{ Number: from.Number, Title: from.Title, @@ -362,14 +369,11 @@ func convertIssue(from *issue) *scm.Issue { Login: from.User.Login, Avatar: from.User.AvatarURL, }, - ClosedBy: closedBy, - Assignees: convertUsers(from.Assignees), - PullRequest: &scm.PullRequest{ - DiffLink: from.PullRequest.DiffURL, - Link: from.PullRequest.HTMLURL, - }, - Created: from.CreatedAt, - Updated: from.UpdatedAt, + ClosedBy: closedBy, + Assignees: convertUsers(from.Assignees), + PullRequest: pullRequest, + Created: from.CreatedAt, + Updated: from.UpdatedAt, } } diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/pr.go index 2ec671b524a..c0baad118d0 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/pr.go @@ -158,6 +158,10 @@ func (s *pullService) UnrequestReview(ctx context.Context, repo string, number i return res, nil } +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + func prepareReviewersBody(logins []string, org string) (prReviewers, error) { body := prReviewers{} var errors []error diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/release.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/release.go index b8526aa8a89..a79dbb38c03 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/github/release.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/github/release.go @@ -66,6 +66,9 @@ func (s *releaseService) Create(ctx context.Context, repo string, input *scm.Rel Prerelease: input.Prerelease, Tag: input.Tag, } + if !(in.Prerelease || in.Draft) { + in.MakeLatest = "true" + } out := new(release) res, err := s.client.do(ctx, "POST", path, in, out) return convertRelease(out), res, err diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/content.go index 82fa1cc2408..24a316c8b90 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/content.go @@ -39,7 +39,7 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm }, res, err } -func (s *contentService) List(ctx context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { +func (s *contentService) List(ctx context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { endpoint := fmt.Sprintf("api/v4/projects/%s/repository/tree?path=%s&ref=%s", encode(repo), path, ref) out := []*entry{} res, err := s.client.do(ctx, "GET", endpoint, nil, &out) diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/git.go index 0ee90de985f..4c7e069e425 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/git.go @@ -123,6 +123,14 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, ref1, ref2 string return convertChangeList(out.Diffs), res, err } +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + repository, res, err := s.client.Repositories.Find(ctx, repo) + if err != nil { + return nil, res, err + } + return s.FindBranch(ctx, repo, repository.Branch) +} + type compare struct { Diffs []*change `json:"diffs"` } diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/pr.go index 2da6fb02b07..83acab6479f 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gitlab/pr.go @@ -266,6 +266,10 @@ func (s *pullService) ClearMilestone(ctx context.Context, repo string, prID int) return res, err } +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + type updateMergeRequestOptions struct { Title *string `json:"title,omitempty"` Description *string `json:"description,omitempty"` diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/content.go index bd7d6ecc65a..39c4592a90c 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/content.go @@ -29,7 +29,7 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm }, res, err } -func (s *contentService) List(ctx context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { +func (s *contentService) List(ctx context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { return nil, nil, scm.ErrNotSupported } diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/git.go index 3253e56b278..2a821d9b927 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/git.go @@ -69,6 +69,14 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, ref1, ref2 string return nil, nil, scm.ErrNotSupported } +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + repository, res, err := s.client.Repositories.Find(ctx, repo) + if err != nil { + return nil, res, err + } + return s.FindBranch(ctx, repo, repository.Branch) +} + // // native data structures // diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/pr.go index c26afc42355..244fe644b8a 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/gogs/pr.go @@ -111,6 +111,10 @@ func (s *pullService) ClearMilestone(ctx context.Context, repo string, prID int) return nil, scm.ErrNotSupported } +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + return nil, scm.ErrNotSupported +} + // // native data structures // diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/content.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/content.go index 5fbe61315c6..603d7d33216 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/content.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/content.go @@ -28,18 +28,72 @@ func (s *contentService) Find(ctx context.Context, repo, path, ref string) (*scm }, res, err } -func (s *contentService) List(ctx context.Context, repo, path, ref string) ([]*scm.FileEntry, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported +func (s *contentService) List(ctx context.Context, repo, path, ref string, opts *scm.ListOptions) ([]*scm.FileEntry, *scm.Response, error) { + namespace, name := scm.Split(repo) + endpoint := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/files/%s?at=%s&%s", namespace, name, path, ref, encodeListOptions(opts)) + out := new(contents) + res, err := s.client.do(ctx, "GET", endpoint, nil, out) + if !out.pagination.LastPage.Bool { + res.Page.First = 1 + res.Page.Next = opts.Page + 1 + } + return convertFileEntryList(out), res, err } func (s *contentService) Create(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - return nil, scm.ErrNotSupported + namespace, repoName := scm.Split(repo) + endpoint := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/browse/%s", namespace, repoName, path) + message := params.Message + if params.Signature.Name != "" && params.Signature.Email != "" { + message = fmt.Sprintf("%s\nSigned-off-by: %s <%s>", params.Message, params.Signature.Name, params.Signature.Email) + } + in := &contentCreateUpdate{ + Message: message, + Branch: params.Branch, + Content: params.Data, + } + return s.client.do(ctx, "PUT", endpoint, in, nil) } func (s *contentService) Update(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { - return nil, scm.ErrNotSupported + namespace, repoName := scm.Split(repo) + endpoint := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/browse/%s", namespace, repoName, path) + message := params.Message + if params.Signature.Name != "" && params.Signature.Email != "" { + message = fmt.Sprintf("%s\nSigned-off-by: %s <%s>", params.Message, params.Signature.Name, params.Signature.Email) + } + in := &contentCreateUpdate{ + Message: message, + Branch: params.Branch, + Content: params.Data, + Sha: params.Sha, + } + + return s.client.do(ctx, "PUT", endpoint, in, nil) } func (s *contentService) Delete(ctx context.Context, repo, path string, params *scm.ContentParams) (*scm.Response, error) { return nil, scm.ErrNotSupported } + +type contents struct { + pagination + Values []string `json:"values"` +} + +type contentCreateUpdate struct { + Branch string `json:"branch"` + Message string `json:"message"` + Content []byte `json:"content"` + Sha string `json:"sourceCommitId"` +} + +func convertFileEntryList(from *contents) []*scm.FileEntry { + var to []*scm.FileEntry + for _, v := range from.Values { + to = append(to, &scm.FileEntry{ + Path: v, + }) + } + return to +} diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/git.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/git.go index 6d9179fddca..ab8b050bfab 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/git.go @@ -41,11 +41,22 @@ func (s *gitService) FindRef(ctx context.Context, repo, ref string) (string, *sc } func (s *gitService) CreateRef(ctx context.Context, repo, ref, sha string) (*scm.Reference, *scm.Response, error) { - return nil, nil, scm.ErrNotSupported + namespace, repoName := scm.Split(repo) + path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/branches", namespace, repoName) + out := new(branch) + in := &createBranch{ + Name: ref, + StartPoint: sha, + } + resp, err := s.client.do(ctx, "POST", path, in, out) + return convertBranch(out), resp, err } func (s *gitService) DeleteRef(ctx context.Context, repo, ref string) (*scm.Response, error) { - return nil, scm.ErrNotSupported + namespace, name := scm.Split(repo) + path := fmt.Sprintf("rest/branch-utils/latest/projects/%s/repos/%s/branches", namespace, name) + in := deleteRefInput{Name: ref} + return s.client.do(ctx, "DELETE", path, &in, nil) } func (s *gitService) FindBranch(ctx context.Context, repo, branch string) (*scm.Reference, *scm.Response, error) { @@ -142,6 +153,20 @@ func (s *gitService) CompareCommits(ctx context.Context, repo, ref1, ref2 string return convertDiffstats(out), res, err } +func (s *gitService) GetDefaultBranch(ctx context.Context, repo string) (*scm.Reference, *scm.Response, error) { + namespace, name := scm.Split(repo) + branch := new(branch) + pathBranch := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/branches/default", namespace, name) + resp, err := s.client.do(ctx, "GET", pathBranch, nil, branch) + return convertBranch(branch), resp, err +} + +type deleteRefInput struct { + DryRun bool `json:"dryRun,omitempty"` + EndPoint string `json:"endPoint,omitempty"` + Name string `json:"name,omitempty"` +} + type branch struct { ID string `json:"id"` DisplayID string `json:"displayId"` @@ -151,6 +176,11 @@ type branch struct { IsDefault bool `json:"isDefault"` } +type createBranch struct { + Name string `json:"name"` + StartPoint string `json:"startPoint"` +} + type branches struct { pagination Values []*branch `json:"values"` @@ -253,10 +283,11 @@ func convertDiffstats(from *diffstats) []*scm.Change { func convertDiffstat(from *diffstat) *scm.Change { to := &scm.Change{ - Path: from.Path.ToString, - Added: from.Type == "ADD", - Renamed: from.Type == "MOVE", - Deleted: from.Type == "DELETE", + Path: from.Path.ToString, + Added: from.Type == "ADD", + Modified: from.Type == "MODIFY", + Renamed: from.Type == "MOVE", + Deleted: from.Type == "DELETE", } if from.SrcPath != nil { to.PreviousPath = from.SrcPath.ToString diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/multipart.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/multipart.go new file mode 100644 index 00000000000..4da89fdb76b --- /dev/null +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/multipart.go @@ -0,0 +1,26 @@ +package stash + +import "mime/multipart" + +type MultipartWriter struct { + Writer *multipart.Writer + Error error +} + +func (mw *MultipartWriter) Write(f, v string) { + if mw.Error != nil { + return + } + if v == "" { + return + } + mw.Error = mw.Writer.WriteField(f, v) +} + +func (mw *MultipartWriter) Close() { + mw.Writer.Close() +} + +func (mw *MultipartWriter) FormDataContentType() string { + return mw.Writer.FormDataContentType() +} diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/pr.go index 2e082d5707c..c5f577d91dc 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/pr.go @@ -51,7 +51,7 @@ func (s *pullService) List(ctx context.Context, repo string, opts *scm.PullReque func (s *pullService) ListChanges(ctx context.Context, repo string, number int, opts *scm.ListOptions) ([]*scm.Change, *scm.Response, error) { namespace, name := scm.Split(repo) - path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/changes", namespace, name, number) + path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/pull-requests/%d/changes?%s", namespace, name, number, encodeListOptions(opts)) out := new(diffstats) res, err := s.client.do(ctx, "GET", path, nil, out) if !out.pagination.LastPage.Bool { @@ -305,6 +305,21 @@ func (s *pullService) ClearMilestone(ctx context.Context, repo string, prID int) return nil, scm.ErrNotSupported } +func (s *pullService) DeletePullRequest(ctx context.Context, repo string, prID int) (*scm.Response, error) { + namespace, name := scm.Split(repo) + // in Bitbucket server (stash) to delete a pull request `version` of the pull request + // must be provided in body of the request so it's worth fetching pull request via rest api + // to get latest version of the pull request. + path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/pull-requests/%d", namespace, name, prID) + out := new(pullRequest) + _, err := s.client.do(ctx, http.MethodGet, path, nil, out) + if err != nil { + return nil, fmt.Errorf("failed to get pull request. err: %v", err) + } + in := map[string]int{"version": out.Version} + return s.client.do(ctx, http.MethodDelete, path, &in, nil) +} + type createPRInput struct { Title string `json:"title,omitempty"` Description string `json:"description,omitempty"` diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/repo.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/repo.go index 2840e95d806..701d99774e8 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/repo.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/repo.go @@ -296,7 +296,17 @@ func (s *repositoryService) Find(ctx context.Context, repo string) (*scm.Reposit path := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s", namespace, name) out := new(repository) res, err := s.client.do(ctx, "GET", path, nil, out) - return convertRepository(out), res, err + outputRepo := convertRepository(out) + + // default value for repository.Branch is `master` but it may differ for other + // repositories as a repository can have `main` or `trunk` as default branch. + branch := new(branch) + pathBranch := fmt.Sprintf("rest/api/1.0/projects/%s/repos/%s/branches/default", namespace, name) + _, errBranch := s.client.do(ctx, "GET", pathBranch, nil, branch) + if errBranch == nil { + outputRepo.Branch = branch.DisplayID + } + return outputRepo, res, err } // FindHook returns a repository hook. @@ -441,15 +451,15 @@ func (s *repositoryService) CreateStatus(ctx context.Context, repo, ref string, State: convertFromState(input.State), Key: input.Label, Name: input.Label, - URL: input.Target, + URL: input.Link, Desc: input.Desc, } res, err := s.client.do(ctx, "POST", path, in, nil) return &scm.Status{ - State: input.State, - Label: input.Label, - Desc: input.Desc, - Target: input.Target, + State: input.State, + Label: input.Label, + Desc: input.Desc, + Link: input.Link, }, res, err } diff --git a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/stash.go b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/stash.go index 83b6ff7aa33..ec743eaf8ba 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/stash.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/driver/stash/stash.go @@ -9,7 +9,9 @@ import ( "bytes" "context" "encoding/json" + "fmt" "io" + "mime/multipart" "net/url" "strings" @@ -74,13 +76,32 @@ func (c *wrapper) do(ctx context.Context, method, path string, in, out interface // if we are posting or putting data, we need to // write it to the body of the request. if in != nil { - buf := new(bytes.Buffer) - err := json.NewEncoder(buf).Encode(in) // #nosec - if err != nil { - return nil, err + switch contentInput := in.(type) { + case *contentCreateUpdate: + var b bytes.Buffer + mw := &MultipartWriter{Writer: multipart.NewWriter(&b)} + mw.Write("content", string(contentInput.Content)) + mw.Write("message", contentInput.Message) + mw.Write("branch", contentInput.Branch) + mw.Write("sourceCommitId", contentInput.Sha) + if mw.Error != nil { + return nil, fmt.Errorf("error writing multipart-content. err: %s", mw.Error) + } + mw.Close() + req.Body = &b + req.Header = map[string][]string{ + "Content-Type": {mw.FormDataContentType()}, + "x-atlassian-token": {"no-check"}, + } + default: + buf := new(bytes.Buffer) + err := json.NewEncoder(buf).Encode(in) // #nosec + if err != nil { + return nil, err + } + req.Header.Add("Content-Type", "application/json") + req.Body = buf } - req.Header.Add("Content-Type", "application/json") - req.Body = buf } req.Header.Add("X-Atlassian-Token", "no-check") diff --git a/vendor/github.com/jenkins-x/go-scm/scm/git.go b/vendor/github.com/jenkins-x/go-scm/scm/git.go index bc6e53c2376..c2af73288d5 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/git.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/git.go @@ -69,6 +69,9 @@ type ( // FindBranch finds a git branch by name. FindBranch(ctx context.Context, repo, name string) (*Reference, *Response, error) + // GetDefaultBranch finds default branch of the repo. + GetDefaultBranch(ctx context.Context, repo string) (*Reference, *Response, error) + // FindCommit finds a git commit by ref. FindCommit(ctx context.Context, repo, ref string) (*Commit, *Response, error) diff --git a/vendor/github.com/jenkins-x/go-scm/scm/pr.go b/vendor/github.com/jenkins-x/go-scm/scm/pr.go index df118450595..f200878c183 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/pr.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/pr.go @@ -94,6 +94,7 @@ type ( Path string PreviousPath string Added bool + Modified bool Renamed bool Deleted bool Patch string @@ -192,6 +193,9 @@ type ( // ClearMilestone removes the milestone from a pull request ClearMilestone(ctx context.Context, repo string, prID int) (*Response, error) + + // DeletePullRequest deletes a pull request from a repo. + DeletePullRequest(ctx context.Context, repo string, prID int) (*Response, error) } ) diff --git a/vendor/github.com/jenkins-x/go-scm/scm/repo.go b/vendor/github.com/jenkins-x/go-scm/scm/repo.go index 77e43e7e2d5..3ec5e0fbc6d 100644 --- a/vendor/github.com/jenkins-x/go-scm/scm/repo.go +++ b/vendor/github.com/jenkins-x/go-scm/scm/repo.go @@ -28,7 +28,7 @@ type ( Name string FullName string Perm *Perm - Branch string + Branch string // default branch of the repository Private bool Archived bool Clone string diff --git a/vendor/modules.txt b/vendor/modules.txt index 5fb64f33112..80ab1970c9c 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -53,6 +53,9 @@ contrib.go.opencensus.io/exporter/prometheus # dario.cat/mergo v1.0.0 ## explicit; go 1.13 dario.cat/mergo +# fortio.org/safecast v1.0.0 +## explicit; go 1.20 +fortio.org/safecast # github.com/42wim/httpsig v1.2.1 ## explicit; go 1.18 github.com/42wim/httpsig @@ -314,8 +317,8 @@ github.com/blang/semver/v4 # github.com/blendle/zapdriver v1.3.1 ## explicit; go 1.12 github.com/blendle/zapdriver -# github.com/bluekeyes/go-gitdiff v0.7.1 -## explicit; go 1.13 +# github.com/bluekeyes/go-gitdiff v0.8.0 +## explicit; go 1.21 github.com/bluekeyes/go-gitdiff/gitdiff # github.com/cenkalti/backoff/v4 v4.3.0 ## explicit; go 1.18 @@ -725,7 +728,7 @@ github.com/jbenet/go-context/io # github.com/jellydator/ttlcache/v3 v3.3.0 ## explicit; go 1.18 github.com/jellydator/ttlcache/v3 -# github.com/jenkins-x/go-scm v1.14.37 +# github.com/jenkins-x/go-scm v1.14.56 ## explicit; go 1.22.3 github.com/jenkins-x/go-scm/pkg/hmac github.com/jenkins-x/go-scm/scm